Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Justin
Justin

Posted on

     

DragonRuby: Following the Mouse

Recently I discovered it is very easy to have objects move towards (or away from) any points inDragonRuby.

This post might be a little easier if you've already read my post onmoving in arbitrary directions, but actually the code here is even simpler.

If I skip any explanations here, the concepts should have been coveredearlier in the series.

Setup

To get started, let's just output a square (roughly) in the middle of the screen.

args.grid.center_x andargs.grid.center_y are helpful for this instead of remembering/hardcoding the screen size.

In addition, the code usesargs.state.tick_count == 0 to do some setup on the first tick.

deftick(args)# On the first tick...ifargs.state.tick_count==0# Create a 50x50 pixel square in the middle of the screenargs.state.player={x:args.grid.center_x,y:args.grid.center_y,h:50,w:50}# Output that square on every tickargs.outputs.static_solids<<args.state.playerendend
Enter fullscreen modeExit fullscreen mode

A square in the middle of a window

Pretty basic!

(Note I'm skipping straight tostatic_solids because that's what I'd prefer in a "real" game.)

Moving to a Point

Now we'll move the "player" to a given point - in this case where the mouse is. In typical DragonRuby fashion,args.inputs.mouse can be used to as a point, even though it has a bunch of other information attached to it.

To get the angle from the player to the mouse, there is a very convenientangle_to method! (Alsoangle_from depending on which way you'd like to go.)

Just likeargs.inputs.mouse, theplayer solid can be treated as if it is a point, too.

One the angle is calculated,vector_x andvector_y will provide the magnitude to move in thex andy directions.

deftick(args)ifargs.state.tick_count==0args.state.player={x:args.grid.center_x,y:args.grid.center_y,h:50,w:50}args.outputs.static_solids<<args.state.playerend# Find angle from the square to the current location of the mouseangle=args.state.player.angle_to(args.inputs.mouse)# Move towards the mouse using the unit vectorargs.state.player.x+=angle.vector_xargs.state.player.y+=angle.vector_yend
Enter fullscreen modeExit fullscreen mode

Square following the mouse around

And... that's it!! Less than 10 lines of code (without comments/spaces) and it just works.

So now let's make it more complicated...

Centering

It is annoying that the player moves so thebottom, right-hand corner meets the mouse, there is a simple fix: useanchor_x andanchor_y. DragonRuby will automatically use the anchor point for calculations.

To learn more about anchor points, see thisearlier post. But typically the values are set to0.5 which means "middle of the object".

deftick(args)ifargs.state.tick_count==0args.state.player={x:args.grid.center_x,y:args.grid.center_y,h:50,w:50,anchor_x:0.5,anchor_y:0.5,}args.outputs.static_solids<<args.state.playerendangle=args.state.player.angle_to(args.inputs.mouse)args.state.player.x+=angle.vector_xargs.state.player.y+=angle.vector_yend
Enter fullscreen modeExit fullscreen mode

Square following the mouse around, but centered

Moving to Classes

I continue to prefer taking an object/class-based approach in my own code. This makes it much easier to manage as the code grows larger, even if it seems silly for these small examples.

In a little departure from previous posts, I am not walking through the code in detail. (Please check out my other posts in this series to learn more!)

The main difference from the above is adding aspeed to the movement calculation. Other than that, this is how I generally move from simple code like the above into a structure more suitable (in my opinion) as the code.

classGameattr_gtkdefinitialize(args)# Separate setup method is easier if you need to# reset during the gamesetup(args)enddefsetup(args)# Since static_sprites persists between ticks,# need to clear it in case of resetargs.outputs.static_sprites.clear@player=Player.new(x:args.grid.center_x,y:args.grid.center_y,h:50,w:50,speed:2)args.outputs.static_sprites<<@playerenddeftick(args)@player.tick(args)endendclassPlayerattr_spritedefinitialize(x:,y:,h:,w:,speed:)@x=x@y=y@h=h@w=w@anchor_x=0.5@anchor_y=0.5@speed=speedenddeftick(args)angle=self.angle_to(args.inputs.mouse)@x+=angle.vector_x*@speed@y+=angle.vector_y*@speedendenddeftick(args)$Game||=Game.new(args)$Game.tick(args)end
Enter fullscreen modeExit fullscreen mode

One minor note if you actually run this code - the square will be white (default for sprites) instead of black (default for solids).

Top comments(1)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
amirrajan profile image
Amir Rajan
  • Joined

This is really a great series of posts. As a thank you for creating these, email me and I’ll hook you up with a lifetime Pro license for free.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I work on Brakeman (security tool for Ruby on Rails) and do other stuff too.
  • Location
    San Francisco Bay Area
  • Education
    UCLA, Seattle University
  • Joined

More fromJustin

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp