How to make my playing field as a grid in Ruby (Gosu)? - ruby

So I'm attempting to make a simple Snake game. However, there's one major problem with that - I don't know how to make my playing field as a grid.
So far I've split my snake into segemnts, which are drawn every time it eats an apple. My turn method looks like that (it's analogical for every direction pretty much):
if #direction == :right
x = #head.x + #speed
y = #head.y
new_segment = Segment.new(#window, self, [x, y])
end
with new_segment being immediately pushed into the array segments.
The problem with that is that the snake is too independant. I'd like to make it move in predetermined rows and columns a.k.a make myself a grid. Could somoene help me with that? Thank you!

Related

How to avoid a hierarchy in ruby classes?

I am processing 2-dimensional shapes in ruby. I have a Point class with x and y attribute, and a Line class which has two end points. Later in the process chain, I often want to identify and process vertical lines slightly differently from horizontal lines, even though both can occur in the same set of Lines. I have mix-ins to do the processing, but often I find the method has something like
if l.vertical?
l.do_something_with_y_coordinate
elsif l.horizontal?
l.do_something_with_x_coordinate
end
I see this pattern quite frequently and I do not like the repetition. I could try to avoid it by identifying instances of Line that are vertical and creating a VerticalLine class, and a HorizontalLine class, but that feels more like .Net than ruby and does not reduce the duplication, just encapsulates it.
Another way might be to have a direction method that returns :x or :y and then a method to "do_something_with direction".
Does anybody else have any suggestions about how to refactor?
It's not "more like .Net", it's more like proper object-oriented encapsulation. If you learned that via .Net, that's fine, but it's a very general approach that dates back decades before .Net or Ruby ever existed.
There's three ways to tackle this problem:
Use an if to split behaviour.
Use subclasses to implement the specific behaviour.
Generalize your code so it doesn't matter if it's vertical or horizontal, the same math is applied in both cases.
In the third case imagine having vector(s) or a matrix which describes the geometry you're manipulating. For example, [0, 1] could represent a vertical line going up, or [-1, 0] a line going to the left depending on your coordinate system. Each iteration you just add that to your base point. The very idea of horizontal or vertical melts away.
In the concrete case I see three suggestions:
1.) Define accessors which map to x and y depending on the two cases:
def s=(value)
if horizontal
x = value
else
y = value
end
end
def t=(value)
if horizontal
y = value
else
x = value
end
end
With this you can delegate to the "right" field dynamically.
2.) Convert your horizontal cases into vertical ones by rotating, then performing the operation and then rotating it back.
3.) Using another representation that doesn't use x and y such as polar coordinates where your differentiates vanishes.

set's membership seems not to work (python)

I am working on a image search algorithm that finds certain shapes of certain colors; to save time I only register half of the shape's perimeter in 2 distinct sets, one for the rows and one for the columns used by the shape. The idea is that whenever I find a point which has the target color, I then check if this point's row and column are in a master set (which have both the previous sets); if they are I skip it, if they are not then I initialize 2 recursive fuctions that register the first row and the first column of the shape.
Since it's for a school project, my images are specially tailored
and the code would be
for y in range(height):
for x in range(width):
if img[y][x] == target:
if y in master_set and x in master_set:
continue
else:
row = set()
column = set()
flood_fillv2_y(img,x,y,target,column)
flood_fillv2_x(img,x,y,target,row)
row=frozenset(row)
column=frozenset(column)
master_set.add(row)
master_set.add(column)
The idea then is to check the len of master_set to see how many shapes I have, but as I said what I get is that y and x are never in the master set so it keeps doing it for all points of the shape, resulting in a wrong number.
It's hard to give a good answer without seeing the whole code, but I can give a guess:
master_set.add(row) literally adds the frozenset row to the master_set, but you probably want all elements from the set to be added to master_set. Take a look at the update() method of sets.
Does this help?

How to print comments at the right side of a matlab graph?

I want to plot only one simple set of data. For example, my plot command could be :
x = (1:10);
y = ones[1,10];
plot(x,y);
In fact, the y data set could have been generated by a previous code, depending on several parameters. I want to print the name of every parameters and there values outside the graph, at the right of it, as if it were a legend. My problem is that I have several parameters to print, but only one set of data.
I tried to do this by the text or legend functions, but it never fit completly my needs.
Could you help me please ?
I think this code should help you out. Its probably easiest to split your figure into two axes, the right one just to hold text:
x = rand(1,10);
y = rand(1,10);
figure % makes your figure
axes('Position', [0.05,0.05,0.45,.9]) % makes axes on left side of your figure
scatter(x,y)
axes('Position', [0.55,0,1,1],'ytick',[],'xtick',[]) %make axes on left side of your figure, turns of ticks
text(0.05,0.85,{'Parameter 1: blah blah';'Parameter 2: bloop bloop';'Parameter 3: ....'},'Interpreter','Latex')
Play around with the numbers in the brackets to resize things as you like.

Proper OO 2D Animation Logic

I'm doing some animation script in RPG Maker XP (made with ruby) that allow you to display moving images. My question here is not strictly about RPG Maker, but in general term. This is the code I found out so far and it works, but with problem :
class Poser
attr_accessor :images
def initialize
#images = Sprite.new
#images.bitmap = RPG::Cache.picture('Character.png') #display picture
#images.x = 540 #place it on the bottom right corner of the screen
#images.y = 180
end
def move(x,y)
#images.x += x
#images.y += y
end
def animate(x,y,step,delay) #Animate moving the picture up and down with delay
forward = true
2.times { #the first loop, do code 2 times of :
step.times {
wait(delay) #wait x frame
if forward
move(x/step,y/step) #move the picture down
else
move(-x/step,-y/step) #move the picture up
end
}
wait(delay*3)
forward = false
}
end
def wait(time)
while time > 0
time -= 1
Graphics.update
end
end
end
Then I create an instance of it and called the method :
$test = Poser.new
$test.animate(0,10,10,10)
What the above code do is to move the picture up and down (just like breathing animation, your head bob up and down)
As you can see, Im using loop functions to move the picture with delay. What I got is, I cannot do anything else until the animation finished. What I meant by "anything else" is such as walking around with my character, talk to NPC, I want to do those things while there is animation being played in the background. In the end, the game "paused" in the loop block.
Is there is another way to do animation without looping, or, anything that doesn't "pause" the screen until animation is finished ? Thanks in advance.
Usually, games use a system called a game loop. A game loop is a loop in the main function of the program that executes as fast as it can. Each time it executes, it executes two functions (or these can be the body of the loop, that's a design choice that you can make): draw and update (update, then draw).
update's job is to change the positions of characters, usually by a formula of position=(x+pixelsPerSecond*secondsSinceLastTick,y+pixelsPerSecond*secondsSinceLastTick) (in game terminology, a tick is an iteration of the game loop). The system of a game loop is optimized for games, because every tick you can execute one tiny piece of each animation, fast enough together that they give an illusion of concurrency (game loops run many times per second).
After update has changed the position of entire objects (eg. a fast NPC is now 5 pixels further to the left), draw is used to draw the scene. draw can do a couple of things. It can draw sprites at the locations indicated by update, and it can also maintain it's own animations (small things like the animation of legs walking -- update shouldn't set the position of the legs in the walking animation, just the new position of the character for this tick).
I'm not sure if I am exactly answering your question, as I know nothing about RPG Maker (so maybe you have to do something else completely), but because you said in general, this is what it is.

Raphael animate based on position not time

I have two path elements. For the sake of description lets just say one is a heart and the other is a square with rounded corners.
I'm trying to get one to interpolate into the other like this:
http://raphaeljs.com/animation.html
This is easy enough to do but I need to do it based off the elements X position and not time.
So as I drag the path element between an Xval of 100 and 200 it will slowly morph into the second path until it finally completes the transformation at an X value of 200.
Does anyone have any idea how I might do this?
I'd use the drag handler (or you could bind to the mousemove event and feed the coordinates in as well) and use that to move between a starting position and a target animation based on the x or y coordinate and using Element.status. Check out the fiddle (based on yours):
And I'm sorry -- I gave you a copy of your own fiddle back originally. Terribly poor form =( Try this one instead:
http://jsfiddle.net/kevindivdbyzero/MqFkP/2/
So far this is what I have come up with:
http://jsfiddle.net/jocose/CkL5F/139/
This works but relies on a delay which I am afraid is going to break on slower machines, and plus it seams really hacky. If anyone knows of a better solution please let me know.

Resources