Code Comment notes on what is a fixed ratio and what is not

self.movex = math.cos(self.angle) * self.amplitude
self.movey = math.sin(self.angle) * self.amplitude

#I couldn’t just add movex/y to the rect because that calculation
#means the rectx/y values are being calculted by the vector PLUS
#the rectx/y meaning the x and y sums probably wont be in line
#with the ratio the vectore intended.
#So I add the vector to the ships position and give rect THAT.
#the difference is that I use the ship’s position as a reference
#so every time I give rectx/y a new value, that value keeps the
#ratio, but just adds the ships starting x/y as a reference point.
#The original didn’t HAVE a refereence point, it just added values
#to rectx/y which means it will change ….

#ok it’s because we keep calculating the vector again because
#we it’s amplitude! If each time we change the vectors amplitude
#we add it to the rectx/y which changes the rectx/y, then we
#are dealing with a ship in a new position and trying to add
#the same vector(but at a new amplitude, point on the line) to
#that NEW starting position.

#let’s take rectx by it’s sef for example. If you change it’s position
#and then add a vectore of a different length to it, you are
#adding to a different rect/x position so it’s …

#I mean, the longer the amplitude, the more it seemed to be in
#line, but without any amplitude, you’re looking at#the cos and sin
#values, and adding those to rect x and y, and then adding them
#again etc.
#We need to go „5+1, 5+2, 5+3
#not „5+1, 6+2, 8+3
#because if cos was 2 but sin was 1
#then it wouldn’t be the right ratio to do things the second
#way for cos and sin, because while you are increasing both
#cos and sin values by the right ratio, by adding them to values
#that then increment at different rates, well then you have values
#of rect x and rect y that GROW at different rates! where as the cos
#and sin grow at the same rates.

#x 5+1 = 6 5+2 = 7 5+3 = 8
#y 5+2 = 7 5+4 = 9 5+6 = 11
#the rate for x is 1 6, 7, 8
#the rate for y is 2 7, 9, 11

#x 5+1 = 6 6+2 = 8 8+3 = 11
#y 5+2 = 7 7+4 = 11 11+6 = 17 y get’s larger FASTER than x
#rate for x is 1, but 6, 8, 11 is not 1 it’s closer to 2.something
#rate for y is 2, but 7, 11, 17 is not 2 it’s closer to 5
#it seems CLOSE to the 1/2 but it’s NOT because…
#11+4 = 15 15+5 = 20
#17+8 = 35 35+10 = 45

#the rates of growth for x here is 5 + 15
#and for y it’s 5+40 because we need to take into account
#what has been added as well for each.
#in the right exampe it will always be x = 5+something
#and y = 5+something*2
#in the wrong example you can see that by the 5th iteration
#15/40 != 1/2

So  this works:
self.rect.x = self.x1 + self.movex
self.rect.y = self.y1 + self.movey

#self.x1 and self.y1 act as references to „5“ in the examples above.

This does not

self.rect.x+= self.movex
self.rect.y+= self.movey

Because the ratio will not not remain fixed.

Pygame level creation: experimenting with 2d arrays text maps

The video just shows the results of my fidgeting lol. I have a level super class which feeds into a sector class with instantiates item, obstacle, and enemy class objects. Then the game loop instantiates the sector class and uses it’s draw method.

Also I have enemies moving around just to make sure I could do that from the 2d array maps initialization. I have these blue guys that close in on the enemy really fast which was my first attempt at what I show in other posts which is inspired by the game Axley fro SNES.

Python’s atan and atan2 functions

This is needed to get an angle based on the rise and run of a vector. So I need this in situations where I need to aim say a turret, and a player sprite and fire. I need to calculate the vector’s rise y2-y1 and run  x2-x1 and put those two parameters into the atan2 function.

There are some things I can’t quite visualize yet but I’ll get to that.

First, there are positive and negative angles. Positive angles are when you go counter clockwise around the unit circle, and negative angles are when you go clockwise. Also, the angle in radians if you go counter clockwise starting from zero, will be the same as that angle if it were positive and going clockwise. enter image description here

so – 45 degrees is positive 315 degrees.

This is important because in aiming something like a turret in the game, having negative angles means you can turn it both ways, instead of having to turn 315 counter clockwise, it can just go clockwise -45 degrees.

So atan2 allows for this by having the parameters for rise and run separate. atan, another math. function, only accepts the already calculated ratio, and so if rise and run were both negative, the result would be positive.

Also for atan, this means the angle then could never be in the 4rd quadrant, the part of the cartesian plane where both y and x are negative.

So the issue in pygame is we a y axis that starts from 0 and goes down from there. So if y1 was 5 and y2 was 10, y2 would be lower than y1 on the screen. I’m trying to get an idea of why the options for fixing this work the way they do.

The first way people fix this is  dy = y1-y2 and then set dy to negative before passing it to atan2. atan2(-dy, dx).

The other way that works for some reason is just flipping the two numbers, atleast when using atan anyways, people are doing atan(dx/dy) and say that works…

I’m going to take a break from it for now but that’s something I’d like to figure out.

Notes on my game programming workflow

1. I create the basic game loop
that displays a titled screen

2. I create the basic classes


3. I define the functions for each clas
trying to use the same name in multiple classes
if I can such as „update“ „animate“, etc.
(because I think that kind of thing comes in handy)
##object images###

4. I create a basic image for a temp class object that has images
using variations of this

width = 40
height = 60
self.image = pygame.Surface([width, height])

5. I set a basic rect for each temp class object
and assign a position for it.

5b. set the updating for each temp class object
so the image remains on each game loop ???

###image initializations###
6. level initialization

####Temp Level initializations
1. in init function init object lists for non player objects
3. create lists with for loops and rand locations
4. add all lists with „.draw“ in draw function
5. update lists „.update“ in update function*not important yet
6. in main before loop instatiate level

level = Level(player) #don’t think „player“ is needed yet

7. In game loop before flip „level.draw“
##(((movement first, then updating becomes needed)))####

7. player initialization

1. in main before loop instatiate player

player = Player()

###initialize temp player locations
player.rect.x = 340
player.rect.y = SCREEN_HEIGHT – player.rect.height

2. in game loop blit starting location

screen.blit(player.image, (340, 500))

8. create add the level shift_world function to
increase the rect.y of all the object so that
they fall off screen away from the player’s ship.

when I do movement I will be able to have acceleration
and reverse affect these

and enemies should be able to ajust for these but not
affect them

9. create „levels“ which will be just sectors and each will initialize
enemies, obstacles, and items for it’s location.
(the „location“ actually doesn’t increase, just that the level
objects increase in rect y until they are off the screen)

10. create a sector list to hold all sectors
create a world_shift var to hold amount world is shifted
if >= 1000 go to next sector of sector list

(although I think each sector should be initialized to start somewhere above
the screen)

In main

###level instantiations/initializations
sector_list = []
temp_sector_1 = sector_1(player)
temp_sector_2 = sector_1(player)

#set current sector
current_sector_no = 0
current_sector = sector_list[current_sector_no]

In loop


if level.world_shift >= 1000:
level.world_shift = 0
current_sector_no += 1
current_sector = sector_list[current_sector_no]

screen.blit(player.image, (340, 500))

Then I add an offest to all sector objects rect.y +1000 so they
are initialized well about the screen
and I change the world_shift conditional to >= 1500

I can clone sectors now to add more to the level and
set and end sector where world shift stops being called and you
just have to collide with the wormhole.
####in no particular order

Now though the drawing has to happen in the sector class instead of the
level class.

obstacles wont have too much to them yet
and I know how to make a basic player
so I’ll focus on all the different types of enemies
…or maybe just 3 to start.

I’m starting to think a scrolling map isn’t a good idea
if this is to big and done fast. I need something more
modular and that I can work on in a more routined way so
I don’t want to have to do so much playing around with
level design at this point.

So I want to make this game instead a series of rooms (although in space,
still rooms) I guess like decent or something iunno)
So I can kind of batch work on all the rooms at once, instead of having
to working on one super long room, and one super big map.
For the enemies a player movement, I have an idea that will also allow
me to do things in a batch like fashion. I will make it so there is one big „ship“
class that holds all possible movement patterns of all ships in the game. Then each
enemy will have one or a few of those and the player ship will be able to gain the
ability to learn those movement patters.

8. movement

I will use the „animation“ function on each class save the „item“ class
and start with basic side to side movement.
9. weapons (need to make a bullet class and maybe have weapons as options
in def shoot)

10. collisions and boundaries (physics engine?)

11. actual map outlines

12. gamestates

13. appearances

14. enemy variation

15. camera (world shift,
for enemies I want to set their location on a map and then
have the world shift and as enemies enter into screen area
they are initialized and attack/move/etc.
I might end up doing collisions last
and movement second to last…

Trigonometry for programming enemies and trajectories

Starting from this site:

I get to the part where he defines:

def move(self):
    self.x += math.sin(self.angle) * self.speed
    self.y -= math.cos(self.angle) * self.speed

I am working on my own little project at the same time and my issue is finding a way to make a circle of enemies close in on the player at their fixed angles. (Like in the first level of Axley for snes!)

On my way home from the library my idea was that the x1-x2/y1-y2 would give a ratio, and then I can subtract a fixed amount from I guess x, and then multiply y by the ratio so that x and y keep the same ratio which should mean the same angle.

However, I want to get this trig stuff cause I feel it will keep being important and in my face. So I wiki’d it and found, „And for a given angle, cos and sin give the respective x, y coordinates on a unit circle.“

Then I wiki’d „unit circle“ and found out that it is like a circle generalized to a radius of one and the angle is at the 0,0 in Cartesian format so the middle of an x,y axis. So sine(self.angle) gives the x value out of a radius of 1, and cos(self.angle) the same, for a given angle. This means that the self.x and self.y that result will be…I can’t think of the word but it’s like generalized lol. It’s that it’s based on a standardized value and has nothing to do with the size of your grid or screen or anything. It’s x and y values based on a unit circle with radius 1. 

This might help. So the max y value is 1, the min y value is also 1. Any other values are somewhere in between including the values calculated in our example.

ok, so self.angle is in radians. So with a fixed angle being initialized, the x and y values, will also be fixed as generalized x and y values. Then incrementing by the sin(self.angle) and cos(self.angle) will result in movement along the fixed angle (self.angle) because incrementing the x and y based on their ratio to a fixed angle maintains that angle.

self.angle = math.pi/2

Make the angle pi/2 = 90 degrees , and you will have a (y) value of zero because 90 degrees is completely horizontal. Oh, and hear I based on how the angle is drawn here startingat the y line and going down. From there 90 degrees is hitting the x line and 180 is hitting the y line at the bottom.

The mathematics of movement

The picture above this one has 90 degrees as the y line which is different I guess.

Path Finding Algorithms + Animation (Mega Man X Study)

This is based on the spider boss of Mega Man X.  The most interesting feature of that boss was that it would produce a web which is basically a graph, and then in would chose almost at random, a path down the web. I say almost because it would sometimes choose a less efficient path to hitting the player, but other times it would seems to choose the shortest path to the player and that made that boss very interesting to fight and even a bit scary.

So I am trying to reproduce that idea with pygame. What I have so far is a black sprite representing the spider, and green gridblocks representing the traversable web, and red representing not part of the web. If you press 4, the shortest path from the hard coded start position, to the hard coded end position, calculated using the basic shortest path dfs algorithm I recently learned. Then the sprite is updated as with position changes based on stepping through the path list.

This path is from (2,0) to (0,5). (x, y)

Spider at start position.
Spider at start position.
Spider on it's way through shortest path.
Spider on it’s way through shortest path.

Then I have an even more basic find first path algorithm. So if you press 3 the spider sprite will just take that path which is longer.

Spider on longer path 1.
Spider on longer path 1.
Spider on longer path 2.
Spider on longer path 2.
Spider on longer path 3.
Spider on longer path 4.
Spider on longer path 4.

Attempts at Path-finding: Some pictures of what I have so far

I have this one graph I generated but it seems to big and finding the shortest path on it just takes way way way too long, I never waited to see how long would actually take. I know there is a way to calculate that but I haven’t learned that yet.

Next is after following this tutorial:

Oh and btw I didn’t follow the tutorial exactly because I try to use classes whenever I can now to get practice. After that I decided to implement path finding with this grid as the basis of a graph. What I need to do tomorrow is use xy tuple coordinates instead of the way I did it which was to add the row and column to try and get an index out of 100. Oh damn I just realized, maybe I need to multiply them instead of add to get an index out of 100 row of 1 to 10 and columns of 1 to 10 yeilds 100 spaces but trying to create indexes by adding the row and column space doesn’t yeild 10o unique positions…iunno I’m tired. lol, so here are the pictures in order of my introductions to them.

The over-sized graph
The over-sized graph
The result of finding just one path on the oversized graph from a start node to an end node.
The result of finding just one path on the oversized graph from a start node to an end node.
The 10X10 grid I turned into a graph and added values 0-2 and colors based on the values. The found a path from 1 -I think 15?
The 10X10 grid I turned into a graph and added values 0-2 and colors based on the values. The found a path from 1 -I think 15?