move Physics2Dserver RID with mouse in Godot - 2d

My goal is detecting the RID when mouse is hovering it and the next goal is to move the RID when the mouse click on it. I have one idea to make this work which is to make another RID which follows the mouse and detect when colliding but just wondering if there's a proper way of getting RID with mouse.
func Create_collision(mouse_position):
xform = Transform2D(1.0 , mouse_position)
#var _shared_Area = Area2D.new()
body = Physics2DServer.body_create()
Physics2DServer.body_set_mode(body, Physics2DServer.BODY_MODE_RIGID)
var _circle_shape = Physics2DServer.circle_shape_create()
Physics2DServer.shape_set_data(_circle_shape, 128)
Physics2DServer.area_add_shape(body, _circle_shape, xform)
Physics2DServer.body_set_space(body, get_world_2d().space)
Physics2DServer.body_set_state(body, Physics2DServer.BODY_STATE_TRANSFORM, Transform2D(0, Vector2(10, 20)))
Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)
return _circle_shape.get_id()
func _body_moved(state, index):
# Created your own canvas item, use it here.
#VisualServer.canvas_item_set_transform(canvas_item, state.transform)
print("moving ojbect",state, index)
another way is to use intersect_point but it does work with RID ojbect for some reason:
example code
func mouse_detect():
#print("get_space()" , get_world_2d().get_space().get_id())
#var space = get_world_2d()
var space = get_world_2d().get_direct_space_state()
#var space = get_canvas_item()
# Get the mouse's position
var mousePos = get_global_mouse_position()
# Check if there is a collision at the mouse position
#if space.intersect_point(mousePos, 1, [], 2147483647, true, true):
#print("hit something",mousePos)
if space.intersect_point(mousePos, 1 , [] ,2147483647 , true , true ):
print("hit something",mousePos ,space)
else:
print("no hit")
#pass
enter code here

the best way to get Collision RID by mouse is using the mouse_detect() function
also this is also the most optimized way. and when adding a image use the visual server with a circle image cause when the VisualServer.canvas_item_add_circle it causes performance issue by 10 times less speed.
var xform : Transform2D
func Create_collision(mouse_position):
xform = Transform2D(1.0 , mouse_position)
var _shared_Area = Area2D.new()
var _circle_shape = Physics2DServer.circle_shape_create()
Physics2DServer.shape_set_data(_circle_shape, 64)
Physics2DServer.area_add_shape(_shared_Area.get_rid(), _circle_shape, xform)
Physics2DServer.area_set_space(_shared_Area, get_world_2d().space)
Physics2DServer.area_set_monitorable(_shared_Area, true)
func _process(delta:float ) -> void:
mouse_detect()
func mouse_detect():
var space = get_world_2d().get_direct_space_state()
var mousePos = get_global_mouse_position()
if space.intersect_point(mousePos, 1, [], 2147483647, true, true):
print(space.intersect_point(mousePos, 1, [], 2147483647, true, true))

Related

Is it possible to make tasklist automatically switch to different layout?

I am using the following code for my wibar tasklist:
s.mytasklist = awful.widget.tasklist
{
screen = s,
filter = awful.widget.tasklist.filter.allscreen,
buttons = tasklist_buttons,
layout = wibox.layout.fixed.horizontal(),
widget_template =
{
{
{
{
id = 'clienticon',
widget = awful.widget.clienticon,
},
margins = 0,
widget = wibox.container.margin,
},
{
id = 'text_role',
widget = wibox.widget.textbox,
},
layout = wibox.layout.fixed.horizontal,
},
id = 'background_role',
forced_width = 200,
forced_height = 60,
widget = wibox.container.background,
create_callback = function(self, c, index, objects)
self:get_children_by_id('clienticon')[1].client = c
end,
},
}
s.mytasklist_onlyminimised = awful.widget.tasklist
{
screen = s,
filter = awful.widget.tasklist.filter.minimizedcurrenttags,
buttons = tasklist_buttons,
style = {
shape_border_width = 1,
shape_border_color = '#333333',
shape = gears.shape.partially_rounded_rect,
},
}
Which makes the tasks on the tasklist have fixed width (as according to this answer)
My question is:
Is it possible to make the tasklist switch to wibox.layout.flex.horizontal when the tasklist is full of tasks?
While you could technically replace the tasklist from a client.connect_signal("tagged", function(c) if #c.screen.selected_tag:clients() >= some_number then <make_a_new_tasklist> end end) style code, that's pretty cheap and ugly.
So I think this would require to contribute a patch upstream to expose the taglist/tasklist constructor arguments as properties. The awful.widget.layoutlist already do it, but not the tag/tasklists.

Lua 2d array defined in object uses pass by reference

I have the following object:
local Game = {}
function Game:new(aNumberOfPlayers, aPlayer1, aPlayer2)
self.NumberOfPlayers = aNumberOfPlayers
self.Player1 = aPlayer1
self.Player2 = aPlayer2
self.Id = HttpService:GenerateGUID(true)
self.Status = "Waiting"
self.Moves = {}
self.Position = GetInitialGamePosition()
return self
end
local Square = {}
function Square:new(x, y, index, color)
self.X = x
self.Y = y
self.Index = index
self.Color = color
return self
end
That uses following function to intialize the 2d array for Position
function GetInitialGamePosition()
local mt = {} -- create the matrix
for i=1,15 do
mt[i] = {}
for j=1,15 do
mt[i][j] = Square:new(i,j,GetIndexFromRowColumn(i,j),nil)
end
end
return mt
end
Problem here is that since tables pass by reference each element of the 2d array ends up being the same. In other words when i iterate over a Position every element has same row, column, and index. Not sure what the best way to get around this is?
function Square:new(x, y, index, color)
local o = {}
o.X = x
o.Y = y
o.Index = index
o.Color = color
setmetatable(o, self)
self.__index = self
return o
end

Update a dependent field in R6 object when a parent field is updated

I'm new to R6 and object oriented programming, so i'm not sure the right way to even talk about dependencies between fields inside an object.
My objects have fields that are dependent on other fields inside the object. I would like those dependent fields to automatically update when one of the inputs is updated.
I have figured out a manual way of doing this, but thought that there may be a better way. I played around with active fields but i could not get them to work.
This example should make it clear. I have an object quad that takes width and height and calculates area. I would like area to be automatically updated when width or height are updated.
This seems to be one of the things that active fields are intended to achieve, but i couldn't make them work.
For the purpose of exposition i hacked to my goal by including a re-calculation line for self$area in the set method for each field.
How is this supposed to be done?
library(R6)
quad <- R6Class("quad", public =
list(width = NULL,
height = NULL,
area = NULL,
initialize = function(width, height) {
self$width <- width
self$height <- height
self$area = self$width * self$height
self$greet()
},
set_width = function(W) {
self$width <- W
self$area = self$width * self$height #hack
},
set_height = function(H) {
self$height <- H
self$area = self$width * self$height #hack
},
greet = function() {
cat(paste0("your quad has area: ", self$area, ".\n"))
})
)
#
> quad1 <- quad$new(5, 5)
your quad has area: 25.
> quad1$set_height(10)
> quad1$area
[1] 50
An active binding is essentially a function that is invoked without needing to use (), so it looks like a regular field.
In the example below, area is an active binding and is computed each time you access it.
library(R6)
Quad <- R6Class(
"Quad",
public = list(
initialize = function(width, height) {
self$width <- width
self$height <- height
},
width = NULL,
height = NULL
),
active = list(
area = function() {
self$width * self$height
}
)
)
q <- Quad$new(8, 3)
q$area
#> [1] 24
q$height <- 5
q$area
#> [1] 40

I want to show a pygame button, which is inherited from pygame.sprite.Sprite, but it is not getting blitted on the display

All
I am building a game with the PYGame library.
I am struggeling with this piece of code, where I want to schow a button. The button is inherited from the pygame.sprite.Sprite class.
I have searched around but I could not find any example wiht a button generated from the pygame.sprite.Sprite class.
#!/usr/bin/env python
import os, sys
import pygame
import numpy
# initialize the pygame module
pygame.init();
if not pygame.font: logging.warning(' Fonts disabled');
class Button(pygame.sprite.Sprite):
def __init__(self, gameplayCode, gameplayLbl, gameplaycolorRGB):
# Call the parent class (Sprite) constructor
super().__init__();
self.gameplayCode = gameplayCode;
self.gameplayLbl = gameplayLbl;
self.gameplaycolorRGB = gameplaycolorRGB;
self.buttondims = self.width, self.height = 190, 60;
self.smallText = pygame.font.SysFont('comicsansms',15);
# calculating a lichter color, needs to be used when hoovering over button
self.color = numpy.array(gameplaycolorRGB);
self.white = numpy.array(pygame.color.THECOLORS['white']);
self.vector = self.white - self.color;
self.gameplaycolorRGBFaded = self.color + self.vector *0.6;
def setCords(self,x,y):
self.textSurf = self.smallText.render(self.gameplayLbl, 1,
pygame.color.THECOLORS['black']);
self.image = pygame.Surface((self.width, self.height));
self.image.fill(self.gameplaycolorRGB);
self.rect = self.image.get_rect();
self.rect.topleft = x,y;
self.rect.center = (x+(x/2),y+(y/2));
def pressed(self,mouse):
if mouse.get_pos()[0] > self.rect.topleft[0]:
if mouse.get_pos()[1] > self.rect.topleft[1]:
if mouse.get_pos()[0] < self.rect.bottomright[0]:
if mouse.get_pos()[1] < self.rect.bottomright[1]:
if mouse.get_pressed()[0] == 1:
return True;
else:
return False;
else:
return False;
else:
return False;
else:
return False;
else:
return False;
def getGamePlayCode(self):
return self.gameplayCode;
def getGamePlayLbl(self):
return self.gameplayLbl;
def getGamePlayColorRGB(self):
return self.gameplaycolorRGB;
def getGamePlayColorRGBFaded(self):
return self.gameplaycolorRGBFaded;
def getButtonWidth(self):
return self.buttondims[0];
def getButtonHeight(self):
return self.buttondims[1];
def getButtonDims(self):
return self.buttondims;
button=Button('CODE','LABEL',pygame.color.THECOLORS['darkturquoise']);
os.environ['SDL_VIDEO_CENTERED'] = '1';
display_size = display_width, display_height = 1300,600;
gameDisplay = pygame.display.set_mode(display_size);
display_xcenter = gameDisplay.get_width()/2;
display_ycenter = gameDisplay.get_height()/2;
# create a background
background = pygame.display.get_surface();
background.fill(pygame.color.THECOLORS['white']);
# put background on the surface
backgroundPos = xcoord, ycoord = 0,0;
gameDisplay.blit(background, backgroundPos);
pygame.display.update();
title='Testing to show a button which is inherited form
pygame.sprite.Sprite. When pressing the button code must react. When
hoovering color must be brighter.';
textSurface = pygame.font.SysFont('comicsansms',15).render(title, True,
pygame.color.THECOLORS['black']);
textRect = textSurface.get_rect();
gameDisplay.blit(textSurface, textRect);
pygame.display.update();
clock = pygame.time.Clock();
FPS = 60;
game_loop = True;
button.setCords(display_xcenter,display_ycenter);
while game_loop:
mouse = pygame.mouse;
for event in pygame.event.get():
if event.type == pygame.QUIT:
print('Quiting');
game_loop = False;
if button.pressed(mouse):
print('Gameplay pressed');
pygame.display.update();
clock.tick(FPS);
# ending the pygame module
pygame.quit();
I want to blit the button, react on the pressed method, when hoovering over the button the color must be brighter.
Any input is highly appreciated.
In the beginning my game didnot had any classes. Now I am rebuilding the game with the use of classes.
Kind Regards
Olivier
-A Python beginner-
Pygame sprites should usually be added to a sprite group (there are several different group types). Then you can update and draw all sprites in your main loop by calling group.update() and group.draw(gameDisplay).
# Create a sprite group and add the button.
buttons = pygame.sprite.Group(button)
# You could also add it afterwards.
# buttons.add(button)
while game_loop:
mouse = pygame.mouse
for event in pygame.event.get():
if event.type == pygame.QUIT:
print('Quiting')
game_loop = False
if button.pressed(mouse):
print('Gameplay pressed')
# This will call the `update` methods of all sprites in
# this group (not necessary here).
buttons.update()
# The display is usually filled each frame (or blit a background image).
gameDisplay.fill(pygame.color.THECOLORS['white'])
# This will draw each sprite `self.image` at the `self.rect` coords.
buttons.draw(gameDisplay)
pygame.display.update()
clock.tick(FPS)

Make image move position when clicked Elm

How should I edit my view so that the image stays in a fixed position when I click a certain position. Currently, it follows the mouse.
update : Msg -> Model -> (Model,Cmd.Cmd Msg)
update (MouseMsg pos) model = ({ model | position = {x = pos.x, y = pos.y} },Cmd.none)
view : Model -> Html.Html Msg
view model = let
posX = toString model.position.x
posY = toString model.position.y
in
svg [ onClick model ][width "10000",height "10000"] [circle [cx posX, cy posY, r "50", fill "blue" ] []]
Sure, easy enough! :)
add a this to your model
dragging : Bool
add this to your update
({ model | dragging = False}, Cmd.none)
and add this to your init
dragging = True

Resources