Jump to content
  • Advertisement

Search the Community

Showing results for tags 'Python'.

The search index is currently processing. Current results may not be complete.


More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Categories

  • Audio
    • Music and Sound FX
  • Business
    • Business and Law
    • Career Development
    • Production and Management
  • Game Design
    • Game Design and Theory
    • Writing for Games
    • UX for Games
  • Industry
    • Interviews
    • Event Coverage
  • Programming
    • Artificial Intelligence
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Engines and Middleware
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
  • Archive

Categories

  • Audio
  • Visual Arts
  • Programming
  • Writing

Categories

  • Game Developers Conference
    • GDC 2017
    • GDC 2018
  • Power-Up Digital Games Conference
    • PDGC I: Words of Wisdom
    • PDGC II: The Devs Strike Back
    • PDGC III: Syntax Error

Forums

  • Audio
    • Music and Sound FX
  • Business
    • Games Career Development
    • Production and Management
    • Games Business and Law
  • Game Design
    • Game Design and Theory
    • Writing for Games
  • Programming
    • Artificial Intelligence
    • Engines and Middleware
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
    • 2D and 3D Art
    • Critique and Feedback
  • Community
    • GameDev Challenges
    • GDNet+ Member Forum
    • GDNet Lounge
    • GDNet Comments, Suggestions, and Ideas
    • Coding Horrors
    • Your Announcements
    • Hobby Project Classifieds
    • Indie Showcase
    • Article Writing
  • Affiliates
    • NeHe Productions
    • AngelCode
  • Topical
    • Virtual and Augmented Reality
    • News
  • Workshops
    • C# Workshop
    • CPP Workshop
    • Freehand Drawing Workshop
    • Hands-On Interactive Game Development
    • SICP Workshop
    • XNA 4.0 Workshop
  • Archive
    • Topical
    • Affiliates
    • Contests
    • Technical
  • GameDev Challenges's Topics
  • For Beginners's Forum

Calendars

  • Community Calendar
  • Games Industry Events
  • Game Jams
  • GameDev Challenges's Schedule

Blogs

There are no results to display.

There are no results to display.

Product Groups

  • GDNet+
  • Advertisements
  • GameDev Gear

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


About Me


Website


Industry Role


Twitter


Github


Twitch


Steam

Found 38 results

  1. I'M interested in programming tools (For animation, UI, etc). Can anyone suggest me the resources where I can start learning or which technologies I need achive it. Thanks, Rakshit
  2. Hello! As my hobby, I’m working on an ice-hockey game, using Python (pygame). It will be based on wego-turns, with each turn representing 3 seconds of “realtime playback”. In other words: both users plan their skaters’ movements and actions for the upcoming 3 seconds while the game is paused, and then, when they both have confirmed their turn, the game takes their plans, calculates what happens and finally presents the outcome of the turn to the users as a 3 seconds-replay. All frames of the action are stored so that users can re-watch the action, using rewind, forward, play functions etc. As I'm almost totally new to programming, I’m worried about the planning phase. Although my code does achieve what I want, I’m worried that it is overly complicated and will give me lots of headaches later on. Therefore, I would be very thankful if someone more experienced in programming could take a look and/or lend me a hand and give me tips how to simplify and shorten it. I will post my code at the end of the post in the spoiler, but I fear that it might be so messed up that noone but me understands it. Here is what the code should do: IDEA Context: When a certain input is given while a skater is selected during the planning phase, planning mode is enabled.In planning mode, the user can set waypoints for the selected skater. The higher the speed of a skater, the narrower the allowed angle to set the next waypoint needs to be. E.g. if your skater goes at full speed, you cannot perform a 90° turn within just two waypoints. The number of waypoints that can be set for a skater in the planning phase depends on the skater’s speed. The greater the speed, the more waypoints can be set. The effect of speed needs to be tracked during the planning-phase itself, so that - for example - if a user sets acceleration-waypoints he will be able to set more waypoints in this very planning-phase. All information for movement (between waypoints) must be stored, as it needs to be retrievable in the replay-phase. If you have any ideas or hints how to come up with a code that achieves these things, please tell me, never mind how basic or in-depth! What follows below is my complicated attempt at it. MY ATTEMPT VIDEO
  3. I'm making a multiplayer third person shooter (TPS) game using a Panda3D engine. It's in an early prototype state. A few videos from my DevLog:
  4. Arnold // Golden Donkey Productions

    C# Where to get started in making a text based MUD?

    Where to get started in making a text based MUD? So I have been making small games for over 3 years now and I'm comfortable in the programming languages that follow: 1. Python (I need a bit of practice with this) 2. C# (I am the most comfortable in this) 3. Java (I know quite a bit but might need to do a tad of research) and I have also done a bit in: 4. JS (I know pretty much nothing here) 5. And some other stuff Anyway, so now you know all that rubbish here goes. What I wan't to do is program a text based MMORPG or a text based MUD. I have basically no clue where to begin so I what I need is some places to start. If anyone has any information on the subject, anything at all, please post it bellow. I will be really appreciated.
  5. A simple arcade game in python.I am currently in class 9th and made this game using python
  6. I've made a very simple map generator as a demo for combat encounters in my game. I plan to have the trees and rocks be cover, while the player's bandits ambush a caravan on the road in the middle. Please, let me know what you think. Criticism is welcome. """ Generates a basic map for combat """ __Author__ = "RidiculousName" __date__ = "3/21/18" import pygame as pg import copy import random def createMap(width, height, trees, rocks, roadWidth): """ creates a combat map :param width: int; 20-60 width of map in squares :param height: int; 20-60 height of map in squares :param trees: int; 0 to (width*height)//5 # of trees in map :param rocks: int; 0 to (width*height)//5 # of rocks in map :param roadWidth: int; 0-10 width of road in map (if value=0, will not have a road) :return: tuple matrix of map """ # variable declarations mapMatrix = [] rowList = [0] * width treeLocations = [] rockLocations = [] colIndex = random.randint(0, height) rowIndex = random.randint(0, width) #error checking if trees > (width * height) // 3: print("ERROR: TOO MANY TREES") return 0 elif rocks > (width * height) // 3: print("ERROR: TOO MANY ROCKS") return 0 # create a blank map full of grass for i in range(height): row = copy.copy(rowList) mapMatrix.append(row) # add trees for i in range(trees): while (rowIndex, colIndex) in treeLocations: colIndex = random.randint(0, height - 1) rowIndex = random.randint(0, width - 1) mapMatrix[rowIndex][colIndex] = 1 treeLocations.append((rowIndex, colIndex)) # add rocks for i in range(rocks): while (rowIndex, colIndex) in treeLocations \ or (rowIndex, colIndex) in rockLocations: colIndex = random.randint(0, height - 1) rowIndex = random.randint(0, width - 1) mapMatrix[rowIndex][colIndex] = 2 rockLocations.append((rowIndex, colIndex)) # add the road if roadWidth > 0: ct = int(roadWidth // 2) road = int(height // 2) while ct > 0: mapMatrix[road + ct] = [3] * width mapMatrix[road - ct] = [3] * width ct -= 1 mapMatrix[road] = [3] * width # convert to tuple for i in range(height): mapMatrix[i] = tuple(mapMatrix[i]) # return return tuple(mapMatrix) def showMap(screen, mapMatrix): """ :param screen: pygame screen object images are blitted to this :param mapMatrix: list matrix contains the map matrix :return: none """ # variable declarations height = pg.display.Info().current_h width = pg.display.Info().current_w x_pos = 0 y_pos = 0 grass = pg.image.load("grass.png").convert() tree = pg.image.load("tree.png").convert() rock = pg.image.load("rock.png").convert() road = pg.image.load("road.png").convert() for i in range(len(mapMatrix)): for j in range(len(mapMatrix[i])): if mapMatrix[i][j] == 0: screen.blit(grass, [x_pos, y_pos]) elif mapMatrix[i][j] == 1: screen.blit(tree, [x_pos, y_pos]) elif mapMatrix[i][j] == 2: screen.blit(rock, [x_pos, y_pos]) elif mapMatrix[i][j] == 3: screen.blit(road, [x_pos, y_pos]) x_pos += 16 y_pos += 16 x_pos = 0 def main(): """ calls functions to allow the game to run """ # variable declarations done = False # initialize pygame pg.init() # make screen object size = (1600, 900) screen = pg.display.set_mode(size) # set window caption pg.display.set_caption("Bandit King") #manages FPS clock = pg.time.Clock() #creates map mapMatrix = createMap(30, 30, 140, 20, 2) while not done: # --- main event loop for event in pg.event.get(): if event.type == pg.QUIT: done = True # --- game logic # --- drawing code showMap(screen, mapMatrix) # --- update screen pg.display.flip() # --- limit to 60 FPS clock.tick(60) #print("height: ", pg.display.Info().current_h, "width: ", pg.display.Info().current_w) pg.quit() if __name__ == "__main__": main()
  7. RidiculousName

    2D Random Map Generation

    I want to make a random map generator in python 3, but I have no idea how to do it. Could someone recommend me a good starting point? What I want to make is a flat 2D overworld-map with roads, rivers, settlements, farmlands, forests, and plains. I don't want to model specific buildings. This is just for a game I'm making where I'd like the player to be able to travel from point to point.
  8. Hello all, I have teamed up with TheGameCreators for them to trial a Python version of AppGameKit in the form of a PYD file that makes AppGameKit commands available to Python 3.6 and greater. Currently this PYD is compiled only for use with the Windows x86 version of Python. It is a free, unlimited version of their commercial product, but it does show the AppGameKit logo for a few seconds on game startup and AppGameKit is mentioned in the window title when in windowed mode. The PYD works with PyInstaller for easy distribution. If you haven't heard of AppGameKit, I would recommend looking over their website. They also have documentation online and an active community forum. I should point out that method names have been changed to follow PEP 8 naming conventions, so they will be similar but different from the online help. I also had to make a few changes mentioned on the project's itch.io page. There is also a PYI file there that can be used with PyCharm for easier access to the same information. As mentioned, this is a trial for them, but if there's a positive response they will extend the project and include a way of compiling an executable without the intro logo and window title text as well as support other OS. Please take a look and feel free to ask me any questions about it here or on the project's community forum on itch.io. AppGameKit for Python project page at itch.io: https://fascimania.itch.io/appgamekit-for-python Original announcement url: https://www.thegamecreators.com/post/announcing-appgamekit-for-python
  9. carPrice = input ("what is the base price of the car?") tax = int (carPrice) * .125 insurance = 250 totalcarPrice = int (carPrice) + int (insurance) + int (tax) print ("total cost of your car including: insurance $",insurance,",") print ("and tax: $",tax," comes to $",totalcarPrice) input () This is a program that figures out all your extra costs, when buying a car. The only mistake I still need to figure out, is what the escape clause is for avoiding having a space at the end of a statement inside a print function. It works fine, the user enters the base cost for the car. Program calculates the tax and adds a previously decided insurance cost. Then the program provides the user with both the individual costs, and the total all-inclusive price of the car. EDIT: After some research not in-book, it turns out that you can avoid the white spaces in between statements by using the function sep = "", which should be treated as a variable - so not inside the quotation marks of the print function, rather, naked inside the brackets. So the final program now looks like this: carPrice = input ("what is the base price of the car?") tax = int (carPrice) * .125 insurance = 250 totalcarPrice = int (carPrice) + int (insurance) + int (tax) print ("total cost of your car including: insurance $",insurance,",", sep = "") print ("and tax: $",tax," comes to $",totalcarPrice, sep = "") input ()
  10. I wrote my first program (not including the false start last time I attempted programming) in Python... and it works! after a few bug fixes it's actually quite small and some would think insignificant. But I'm getting used to the syntax and form of the language. print ("hello") print ("nwhat are your 2 favourite foods of all time?") food1 = input ("nt1.") food2 = input ("nt2.") print ("I have made ",food2+food1," for you!") input ("press a key to exit and enjoy your meal :)")
  11. tip15 = 0 tip20 = 0 price = input ("how much did your meal cost?") tip15 = int (price) * .15 tip20 = int (price) * .2 print ("A 20% tip would be ",tip20," and a 15% tip would be",tip15) input () I wrote a tipper program for an exercise. It's a simple program and it took 20mins to write including several bug fixes, where I had to go back to looking through the textbook and a few glances at my first program, before I got it running properly. I made the usual noob mistakes - since I've tackled many different languages, I had to figure out if I needed to declare variables. I also got the variable on the wrong side of the equals sign, then I forgot to include commas in my print statement for the variables. I also forgot to state that the variable was an integer. Finally, I forgot to use brackets and then incorrectly included the calculation inside the brackets. Eventually, I figured all of this out and came up with the above seemingly simple program. And it works! I'm still not using comments, but I'll fix that when I start writing longer programs.
  12. So it took one day to write and bug fix. Then another day to go through guesswork and figuring it out - to get the program to work. I haven't got up to while loops in the book, so it took a while - a few errors before I got it working. And I certainly haven't got as far as def methods, so using them was difficult and problematic. But I wanted my program to be complete with an exit option. import random def end_game(): end_message = ("game over") print (end_message) def game(): againPlay = "y" while againPlay == "y": nmCookie = random.randrange(5) begin = input ("cookie time, open your fortune cookie") if nmCookie < 1: print ("you are going to die someday") againPlay = input ("Still hungry") elif nmCookie == 1: print ("you just ate a cookie") againPlay = input ("Still hungry") elif nmCookie == 2: print ("you are going to eat another cookie") againPlay = input ("Still hungry") elif nmCookie == 3: print ("you like cookies") againPlay = input ("Still hungry") elif nmCookie == 4: print ("you will have a gargantuan legacy") againPlay = input ("Still hungry") else: end_game() game () end_game ()
  13. Hi all, I am starting to develop a tactics game and ran into a problem I had not thought of. I began by drawing a screen with a hex grid, and this is no big deal. I got that working fine. But, I realized it didn't look quite right. This is because in most strategy games, you're not looking straight down. There is a bit of a tilt. Attached is an example of what I mean. The hexagons on bottom are larger than the hexagons on top, and I'm unsure of how to go about adding this effect. Especially when you consider that some maps may be of different sizes. I'm not sure if this is the right place to post something like this, but it seems as though some sort of linear transformation would be applied? No? I don't even know where to begin in a problem like this. Thanks.
  14. Hey folks, new here I've decided to take the advice in this article. So any comments and criticisms on my pong clone would be appreciated! Written using Python 3 and Pygame. Github repo: available here. Thanks! import pygame import random import colour_constants import time import json import math from pathlib import Path SCREEN_SIZE = (640, 480) BALL_DIAMETER = 32 MAX_FPS = 60 PADDLE_SIZE = (16, 64) PADDLE_VEL = 10 HORIZONTAL_BAR = (SCREEN_SIZE[0], PADDLE_SIZE[0]) RECENT_HIT_RESET = 20 BLACK = colour_constants.DISPLAYBLACK PUREBLACK = colour_constants.PUREBLACK #Easy access for colorkeying SETTINGS_PATH = "config_pong.cfg" GAME_INTENSIFYING_CONSTANT = 1.08 COLOUR = colour_constants.APPLE2 player_one_up = pygame.K_q player_one_down = pygame.K_a player_two_up = pygame.K_o player_two_down = pygame.K_l points_per_game = 5 pygame.mixer.pre_init(44100, -16, 2, 2048) pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32) font = pygame.font.SysFont("Mono", 32) try: bounce_sound = pygame.mixer.Sound('bounce.wav') score_sound = pygame.mixer.Sound('score.wav') paddle_sound = pygame.mixer.Sound('paddle_bounce.wav') menu_sound = pygame.mixer.Sound('menu.wav') except: raise UserWarning("Couldn't load sound files.") class Play_Background: def __init__(self): self.surface = pygame.Surface(SCREEN_SIZE) self.surface.fill(BLACK) self.surface = self.surface.convert() pygame.draw.rect(self.surface, COLOUR, (0, 0, HORIZONTAL_BAR[0], HORIZONTAL_BAR[1])) pygame.draw.rect(self.surface, COLOUR, (0, SCREEN_SIZE[1] - HORIZONTAL_BAR[1], HORIZONTAL_BAR[0], HORIZONTAL_BAR[1])) pygame.draw.line(self.surface, COLOUR, (SCREEN_SIZE[0]//2, 0), (SCREEN_SIZE[0]//2, SCREEN_SIZE[1])) def draw(self) -> None: screen.blit( self.surface, (0, 0) ) class vector2: def __init__(self, x, y): self.x = x self.y = y def get_magnitude(self): return math.sqrt(self.x**2 + self.y**2) def normalize(self): magnitude = self.get_magnitude() self.x /= magnitude self.y /= magnitude def __add__(self, rhs): return vector2(self.x + rhs.x, self.y + rhs.y) def __mul__(self, scalar): return vector2(self.x * scalar, self.y * scalar) class Paddle: def __init__(self, side, player, up_button=None, down_button=None): if side == "left": self.pos = vector2(SCREEN_SIZE[0]//40, SCREEN_SIZE[1]//2 - PADDLE_SIZE[1]//2) elif side == "right": self.pos = vector2(SCREEN_SIZE[0] - PADDLE_SIZE[0] - SCREEN_SIZE[0]//40, SCREEN_SIZE[1]//2 - PADDLE_SIZE[1]//2) else: raise ValueError("Illegal 'side' argument sent to Paddle.__init__:", side) if player and (up_button == None or up_button == None): raise ValueError("Illegal combination of player and buttons sent to Paddle.__init__. None buttons make no sense for player == True") self.side = side self.player = player self.up_button = up_button self.down_button = down_button self.vel = vector2(0, 0) #No initial movement. self.surface = pygame.Surface( (PADDLE_SIZE[0], PADDLE_SIZE[1]) ) self.surface.fill(COLOUR) self.surface = self.surface.convert() self.score = 0 if not player: self.wait_to_calculate = 0 if not player: self.last_ball_dir = "left" if not player: self.expected_pos = 0 def calculate_expected_pos(self, ball): posVec = vector2(ball.pos.x + BALL_DIAMETER//2, ball.pos.y + BALL_DIAMETER//2) velVec = vector2(ball.vel.x, ball.vel.y) while True: timer = 1/(MAX_FPS) posVec.x += velVec.x * timer posVec.y += velVec.y * timer #Pseudo_horizontal_bar_check_and_adjustment if posVec.y - BALL_DIAMETER//2 < HORIZONTAL_BAR[1]: velVec.y *= -1 posVec.y = HORIZONTAL_BAR[1] + BALL_DIAMETER//2 elif posVec.y + BALL_DIAMETER//2 > SCREEN_SIZE[1] - HORIZONTAL_BAR[1]: velVec.y *= -1 posVec.y = SCREEN_SIZE[1] - BALL_DIAMETER//2 - HORIZONTAL_BAR[1] #Now for the bounce from the left side, if any if posVec.x - BALL_DIAMETER//2 < 0: posVec.x = BALL_DIAMETER//2 velVec.x *= -1 #And finally, handling for when found the expected pos if posVec.x + BALL_DIAMETER//2 > SCREEN_SIZE[0] - PADDLE_SIZE[0]: return posVec def calculate_expected_drift(self, case): yVel = self.vel.y yPos = self.pos.y while yVel > 5: yVel -= yVel / (MAX_FPS * 1.3) #movesim yPos += yVel * 1/MAX_FPS if yPos < HORIZONTAL_BAR[1]: yVel *= -0.75 yPos = HORIZONTAL_BAR[1] elif yPos + PADDLE_SIZE[1] > SCREEN_SIZE[1] - HORIZONTAL_BAR[1]: yVel *= -0.75 yPos = SCREEN_SIZE[1] - PADDLE_SIZE[1] - HORIZONTAL_BAR[1] if yPos + PADDLE_SIZE[1]//3 - self.expected_pos.y > PADDLE_SIZE[1]//4: return "under" elif (yPos + PADDLE_SIZE[1] - PADDLE_SIZE[1]//3) - self.expected_pos.y < -PADDLE_SIZE[1]//4: return "over" else: return "drift" def move(self, time_passed, ball) -> None: #Accelerate if self.player: pressed_keys = pygame.key.get_pressed() if pressed_keys[self.up_button]: self.vel.y -= PADDLE_VEL elif pressed_keys[self.down_button]: self.vel.y += PADDLE_VEL else: self.vel.y -= self.vel.y / (MAX_FPS * 1.3) #Found experimentally else: if self.expected_pos == 0: self.expected_pos = self.calculate_expected_pos(ball) if ball.vel.x > 0: self.last_ball_dir = "right" if self.wait_to_calculate > 0: self.wait_to_calculate -= 1 else: self.expected_pos = self.calculate_expected_pos(ball) self.wait_to_calculate = RECENT_HIT_RESET//2 elif ball.vel.x < 0: if self.last_ball_dir == "right": self.last_ball_dir = "left" self.expected_pos = self.calculate_expected_pos(ball) self.wait_to_calculate = 0 probable_drift = self.calculate_expected_drift("larger") #expected_pos y is larger than self y if probable_drift == "under": self.vel.y -= PADDLE_VEL elif probable_drift == "over": self.vel.y += PADDLE_VEL else: if abs(self.pos.y + PADDLE_SIZE[1]//2 - self.expected_pos.y) > PADDLE_SIZE[1]: if self.pos.y + PADDLE_SIZE[1]//2 > self.expected_pos.y: self.vel.y -= PADDLE_VEL else: self.vel.y += PADDLE_VEL self.vel.y -= self.vel.y / (MAX_FPS * 1.3) #Move self.pos.y += self.vel.y * time_passed if self.pos.y < HORIZONTAL_BAR[1] or self.pos.y + PADDLE_SIZE[1] > SCREEN_SIZE[1] - HORIZONTAL_BAR[1]: paddle_sound.play() self.vel.y *= -0.75 if self.pos.y < HORIZONTAL_BAR[1]: self.pos.y = HORIZONTAL_BAR[1] else: self.pos.y = SCREEN_SIZE[1] - PADDLE_SIZE[1] - HORIZONTAL_BAR[1] def draw(self) -> None: screen.blit(self.surface, (self.pos.x, self.pos.y)) class Ball: def reset(self) -> None: self.last_hit = None self.pos = vector2(SCREEN_SIZE[0]//2, SCREEN_SIZE[1]//2) self.vel = vector2(SCREEN_SIZE[0] * random.random(), SCREEN_SIZE[1] * random.random()) if random.random() < 0.5: self.vel.x *= -1 if random.random() < 0.5: self.vel.y *= -1 if abs(self.vel.x) < SCREEN_SIZE[0] * 0.1: self.reset() def __init__(self): self.pos = None self.vel = None self.surface = pygame.Surface( (BALL_DIAMETER, BALL_DIAMETER) ) self.surface.set_colorkey(PUREBLACK) pygame.draw.circle( self.surface, COLOUR, (BALL_DIAMETER//2, BALL_DIAMETER//2), BALL_DIAMETER//2) self.surface = self.surface.convert_alpha() self.last_hit = None self.reset() def horizontal_bar_check_and_adjustment(self) -> None: if self.pos.y < HORIZONTAL_BAR[1] or self.pos.y + BALL_DIAMETER > SCREEN_SIZE[1] - HORIZONTAL_BAR[1]: self.vel.y *= -1 bounce_sound.play() if self.pos.y < HORIZONTAL_BAR[1]: self.pos.y = HORIZONTAL_BAR[1] else: self.pos.y = SCREEN_SIZE[1] - BALL_DIAMETER - HORIZONTAL_BAR[1] def score_check(self) -> str: #Can also return None! if self.pos.x + BALL_DIAMETER < 0: return "right" elif self.pos.x > SCREEN_SIZE[0]: return "left" else: return None def simple_collision_check(self, paddles) -> Paddle: #Can also return None! left = paddles[0] right = paddles[1] if self.pos.x + BALL_DIAMETER < right.pos.x and self.pos.x > left.pos.x + PADDLE_SIZE[0]: return None #If we progress below here, a hit might happen... since the ball isn't *between* the paddles! if self.pos.x + BALL_DIAMETER > right.pos.x: #Ball might have hit the right paddle. if self.pos.y > right.pos.y + PADDLE_SIZE[1]: return None elif self.pos.y + BALL_DIAMETER < right.pos.y: return None else: return right else: #Ball might have hit the left paddle. if self.pos.y > left.pos.y + PADDLE_SIZE[1]: return None elif self.pos.y + BALL_DIAMETER < left.pos.y: return None else: return left def collision_handling(self, paddle) -> None: steps = PADDLE_SIZE[1]//2 + BALL_DIAMETER//2 extreme = 1.12 #arcsin(0.9) = 1.12 hit = self.pos.y + BALL_DIAMETER//2 - (paddle.pos.y + PADDLE_SIZE[1]//2) w = extreme/steps*hit newVec = 0 #This is a unit vector, hehe. if paddle.side == "left": newVec = vector2(-math.cos(w), -math.sin(w)) else: newVec = vector2(math.cos(w), -math.sin(w)) magnitude = self.vel.get_magnitude() * GAME_INTENSIFYING_CONSTANT * -1 self.vel.normalize() newVec = newVec + self.vel #The two vectors can be scalar multiplied by some percentage for different admixtures. newVec.normalize() newVec = newVec * magnitude self.vel = newVec def move(self, time_passed, paddles) -> None: self.pos.x += self.vel.x * time_passed self.pos.y += self.vel.y * time_passed self.horizontal_bar_check_and_adjustment() quick_collision = self.simple_collision_check(paddles) #quick_collision will contain a paddle - or None. if quick_collision: if quick_collision.side != self.last_hit: bounce_sound.play() self.last_hit = quick_collision.side self.collision_handling(quick_collision) def draw(self) -> None: screen.blit(self.surface, (self.pos.x, self.pos.y)) class Scoredrawer: def __init__(self): self.left = 0 self.right = 0 def draw(self, left, right): #Idea for improved performance: Check whether there's a change to a score and then only rendering if so. left_text = font.render(str(left), False, COLOUR).convert_alpha() right_text = font.render(str(right), False, COLOUR).convert_alpha() y_offset = HORIZONTAL_BAR[1] * 1.5 screen.blit(left_text, (SCREEN_SIZE[0]//2 - 32 - left_text.get_width(), y_offset)) screen.blit(right_text, (SCREEN_SIZE[0]//2 + 32, y_offset)) def display_winner(winner) -> None: winner_text = font.render( winner.capitalize() + " has won!", False, COLOUR).convert_alpha() screen.blit(winner_text, (SCREEN_SIZE[0]//2 - winner_text.get_width()//2, SCREEN_SIZE[1]//2 - winner_text.get_height()//2)) pygame.display.update() while True: for event in pygame.event.get(): if event.type == pygame.constants.QUIT: exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: exit() elif event.key == pygame.K_RETURN: return def play(win_score: int, two_player_mode: bool) -> str: #returns 'left' or 'right' depending on which player won clock = pygame.time.Clock() background = Play_Background() scoredrawer = Scoredrawer() ball = Ball() paddle1 = Paddle(side="left", player=True, up_button=player_one_up, down_button=player_one_down) paddle2 = Paddle(side="right", player=two_player_mode, up_button=player_two_up, down_button=player_two_down) paddles = [paddle1, paddle2] #Left side must go in paddles[0], right side in paddles[1]. while True: for event in pygame.event.get(): if event.type == pygame.constants.QUIT: exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: exit() time_passed = clock.tick(MAX_FPS) / 1000.0 #time_passed is in seconds background.draw() ball.move(time_passed, paddles) for paddle in paddles: paddle.move(time_passed, ball) scorer = ball.score_check() #Either "left", "right" or None if scorer: score_sound.play() if scorer == "left": paddles[0].score += 1 if paddles[0].score >= win_score: display_winner(scorer) return else: paddles[1].score += 1 if paddles[1].score >= win_score: display_winner(scorer) return ball.reset() scoredrawer.draw(paddles[0].score, paddles[1].score) ball.draw() for paddle in paddles: paddle.draw() pygame.display.update() def display_intro() -> None: display_font = pygame.font.SysFont("mono", SCREEN_SIZE[0]//6) display_text = display_font.render("PongyPong", False, COLOUR, BLACK).convert() display_font2 = pygame.font.SysFont("mono", SCREEN_SIZE[0]//18) display_text2 = display_font2.render("by: Arthur", False, COLOUR, BLACK).convert() for i in range(256): screen.fill(BLACK) display_text.set_alpha(i) screen.blit(display_text, (SCREEN_SIZE[0]//2 - display_text.get_width()//2, SCREEN_SIZE[1]//2 - display_text.get_height())) pygame.display.update() time.sleep(1/100) for i in range(256): display_text2.set_alpha(i) screen.blit(display_text2, (SCREEN_SIZE[0]//2, SCREEN_SIZE[1]//2)) pygame.display.update() time.sleep(1/200) time.sleep(0.25) def settings_menu() -> None: def save_settings(dummy): current_settings = {'COLOUR':COLOUR, 'player_one_up':player_one_up, 'player_one_down':player_one_down, 'player_two_up':player_two_up, 'player_two_down':player_two_down, 'points_per_game':points_per_game} with open(SETTINGS_PATH, 'w') as settings_file: json.dump(current_settings, settings_file) def set_key(var): press_message = font.render( "Press the desired key...", False, COLOUR).convert_alpha() screen.blit(press_message, (SCREEN_SIZE[0]//2 - press_message.get_width()//2, SCREEN_SIZE[1] - font.get_linesize() * 1.5)) pygame.display.update() pygame.event.clear() while True: for event in pygame.event.get(): if event.type == pygame.constants.QUIT: exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: exit() if event.key != pygame.K_RETURN: menu_sound.play() globals()[var] = event.key return selection = 0 options = [{'Text': 'Points Per Game: ', 'func': lambda x: None, 'var': 'points_per_game', 'extradraw': ['arrows', 'value']}, {'Text': 'Colour', 'func': lambda x: None, 'var': 'COLOUR', 'extradraw':'arrows'}, {'Text': 'Player One Up: ', 'func': set_key, 'var': 'player_one_up', 'extradraw':'button'}, {'Text': 'Player One Down: ', 'func': set_key, 'var': 'player_one_down', 'extradraw':'button'}, {'Text': 'Player Two Up: ', 'func': set_key, 'var': 'player_two_up', 'extradraw':'button'}, {'Text': 'Player Two Down: ', 'func': set_key, 'var':'player_two_down', 'extradraw':'button'}, {'Text': 'Save Settings', 'func': save_settings, 'var': 'return', 'extradraw': None}] colour_options = [colour_constants.AMBER, colour_constants.LTAMBER, colour_constants.GREEN1, colour_constants.APPLE1, colour_constants.GREEN2, colour_constants.APPLE2, colour_constants.GREEN3] colour_selection = 0 for i, colour in enumerate(colour_options): if colour == COLOUR: colour_selection = i blinker = True while True: for event in pygame.event.get(): if event.type == pygame.constants.QUIT: exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: exit() elif event.key == pygame.K_RETURN: menu_sound.play() options[selection]['func'](options[selection]['var']) if options[selection]['var'] == 'return': return elif event.key in [pygame.K_DOWN, player_one_down, player_two_down]: menu_sound.play() if selection == len(options) - 1: selection = 0 else: selection += 1 elif event.key in [pygame.K_UP, player_one_up, player_two_up]: menu_sound.play() if selection == 0: selection = len(options) - 1 else: selection -= 1 elif event.key == pygame.K_RIGHT: var = options[selection]['var'] if var == 'COLOUR': menu_sound.play() if colour_selection == len(colour_options) -1: colour_selection = 0 else: colour_selection += 1 globals()[var] = colour_options[colour_selection] elif var == 'points_per_game': menu_sound.play() globals()[var] += 1 elif event.key == pygame.K_LEFT: var = options[selection]['var'] if var == 'COLOUR': menu_sound.play() if colour_selection == 0: colour_selection = len(colour_options) - 1 else: colour_selection -= 1 globals()[var] = colour_options[colour_selection] if var == 'points_per_game': menu_sound.play() globals()[var] = max(1, points_per_game - 1) screen.fill(BLACK) DIV = 32 for i in range(len(options)): if i == selection: blinker = not blinker if blinker: continue text = font.render(options[i]['Text'], False, COLOUR).convert_alpha() screen.blit(text, (SCREEN_SIZE[0]//2 - text.get_width()//2, SCREEN_SIZE[1]//DIV + font.get_linesize() * 1.5 * i)) extradraw = options[i]['extradraw'] if extradraw == 'arrows' or (type(extradraw) == list and 'arrows' in extradraw): h = text.get_height() * 0.75 // 1 arrowsurface = pygame.Surface( (h, h) ) arrowsurface.fill(BLACK) pygame.draw.polygon(arrowsurface, COLOUR, ( (0, h//2), (h//2 - h//8, h//4), (h//2 - h//8, 3*h//4) ) ) pygame.draw.polygon(arrowsurface, COLOUR, ( (h, h//2), (h//2 + h//8, h//4), (h//2 + h//8, 3*h//4) ) ) arrowsurface.convert() screen.blit(arrowsurface, (SCREEN_SIZE[0]//2 - text.get_width()//2 - arrowsurface.get_width() - 2, SCREEN_SIZE[1]//DIV + font.get_linesize() * 1.5 * i + h//8)) if extradraw == 'value' or (type(extradraw) == list and 'value' in extradraw): valuesurface = font.render( str(globals()[options[i]['var']]), False, COLOUR).convert_alpha() screen.blit(valuesurface, (SCREEN_SIZE[0]//2 + text.get_width()//2 + 2, SCREEN_SIZE[1]//DIV + font.get_linesize() * 1.5 * i)) if extradraw == 'button' or (type(extradraw) == list and 'button' in extradraw): buttonsurface = font.render( pygame.key.name(globals()[options[i]['var']]), False, COLOUR).convert_alpha() screen.blit(buttonsurface, (SCREEN_SIZE[0]//2 + text.get_width()//2 + 2, SCREEN_SIZE[1]//DIV + font.get_linesize() * 1.5 * i)) pygame.display.update() def main_menu() -> None: def one_player_mode(): play(points_per_game, False) def two_player_mode(): play(points_per_game, True) selection = 0 options = [{'Text': '1-Player', 'func': one_player_mode}, {'Text': '2-Player', 'func': two_player_mode}, {'Text': 'Settings', 'func': settings_menu}, {'Text': 'Exit', 'func': exit}] blinker = True while True: for event in pygame.event.get(): if event.type == pygame.constants.QUIT: exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: exit() elif event.key == pygame.K_RETURN: menu_sound.play() options[selection]['func']() elif event.key in [pygame.K_DOWN, player_one_down, player_two_down]: menu_sound.play() if selection == len(options) - 1: selection = 0 else: selection += 1 elif event.key in [pygame.K_UP, player_one_up, player_two_up]: menu_sound.play() if selection == 0: selection = len(options) - 1 else: selection -= 1 screen.fill(BLACK) pseudopaddle = pygame.Surface( (PADDLE_SIZE[0]//2, PADDLE_SIZE[1]//2) ) pseudopaddle.fill(COLOUR) pseudopaddle = pseudopaddle.convert() screen.blit(pseudopaddle, (SCREEN_SIZE[0]//2 - PADDLE_SIZE[1], SCREEN_SIZE[1]//10 - PADDLE_SIZE[0]//2)) screen.blit(pseudopaddle, (SCREEN_SIZE[0]//2 + PADDLE_SIZE[1], SCREEN_SIZE[1]//10 + PADDLE_SIZE[0]//2)) pseudoball = pygame.Surface( (BALL_DIAMETER//2, BALL_DIAMETER//2) ) pseudoball.fill(BLACK) pygame.draw.circle( pseudoball, COLOUR, (BALL_DIAMETER//4, BALL_DIAMETER//4), BALL_DIAMETER//4) pseudoball = pseudoball.convert() screen.blit(pseudoball, (SCREEN_SIZE[0]//2 + BALL_DIAMETER//4, SCREEN_SIZE[1]//10 - BALL_DIAMETER//4)) for i in range(len(options)): if i == selection: blinker = not blinker if blinker: continue text = font.render(options[i]['Text'], False, COLOUR).convert_alpha() screen.blit(text, (SCREEN_SIZE[0]//2 - text.get_width()//2, SCREEN_SIZE[1]//4 + font.get_linesize() * 2 * i)) pygame.display.update() def load_settings() -> None: settings_path = Path(SETTINGS_PATH) if settings_path.is_file(): with open(SETTINGS_PATH, 'r') as settings_file: settings = json.load(settings_file) for item in settings: globals()[item] = settings[item] else: default_settings = {'COLOUR':COLOUR, 'player_one_up':player_one_up, 'player_one_down':player_one_down, 'player_two_up':player_two_up, 'player_two_down':player_two_down, 'points_per_game':points_per_game} with open(SETTINGS_PATH, 'w') as settings_file: json.dump(default_settings, settings_file) if __name__ == '__main__': load_settings() display_intro() main_menu()
  15. I was looking for a library to make a server/clients program. I was thinking there would be easy tutorials for Javascript or Java. What I ran across that is interesting is a Python tutorial for teens that looks pretty easy. https://www.raywenderlich.com/38732/multiplayer-game-programming-for-teens-with-python I don't know too much about Python though and I am wondering if the language is worthwhile. Is it supported? Also, I am interested in the possible use of a relational database, of which I found : PostgreSQL. If you know Python could you please give me a recommendation. Its future, use, popularity, IDE, Database suggested? From what I see it looks like an understandable language. One of the highly recommended IDEs called Pycharm has no database support, so I stopped here and thought I'd bring it up in this forum. I'm interested in any free versions too, EDIT: Pygame is a download needed : https://www.raywenderlich.com/24252/beginning-game-programming-for-teens-with-python Thank you; maybe you have alternate suggestions? Josheir
  16. Tazbird

    Projectile Dominion: Gameplay 2

    From the album: MissileCommandChallenge2018

    Additional game play from my 2018 Missile Command Challenge Submission
  17. Tazbird

    Projectile Dominion: Ending Screen

    From the album: MissileCommandChallenge2018

    The ending screen from my 2018 Missile Command Challenge submission
  18. Tazbird

    Projectile Dominion: Game Play

    From the album: MissileCommandChallenge2018

    Game play from my 2018 Missile Command Challenge Submission
  19. Tazbird

    Projectile Dominion: Title Screen

    From the album: MissileCommandChallenge2018

    The title screen to my 2018 Missile Command Challenge submission
  20. I want to make it so the location and size of the buttons I use are changed to suit the background image when the screen is resized. Here is my code so far: """ Combines various .py files and allows the game to run. """ from kivy.app import App from kivy.uix.image import Image from kivy.config import Config from kivy.uix.button import Button from kivy.uix.floatlayout import FloatLayout class MainMenu(FloatLayout): def __init__(self, **kwargs): super(MainMenu, self).__init__(**kwargs) start_button = Button(pos=(25, 75), background_normal="Start.png", background_down="Start_Down.png", size_hint=(.1, .1)) load_button = Button(pos=(225, 75), background_normal="Load.png", background_down="Load_Down.png", size_hint=(.1, .1)) options_button = Button(pos=(425, 75), background_normal="Options.png", background_down="Options_Down.png", size_hint=(.150, .1)) quit_button = Button(pos=(708, 75), background_normal="Quit.png", background_down="Quit_Down.png", size_hint=(.1, .1)) background = Image(source="Main_Menu.png", pos=(0, 0)) self.add_widget(background) self.add_widget(start_button) self.add_widget(load_button) self.add_widget(options_button) self.add_widget(quit_button) class BanditKing(App): def build(self): self.title = "Bandit King" self.icon = "Window_Icon.png" return MainMenu() def main(): Config.set("graphics", "width", "1600") Config.set("graphics", "height", "900") Config.write() BanditKing().run() if __name__ == "__main__": main() Here is what it should always look like. Here is what it does: You might be able to tell the "Options" button is slightly off line with the other buttons. I would also like to know how to fix that.
  21. Bob Dylan

    SAT not working properly

    Here is my implementation of SAT, it does not work properly as the title says, in that it quite frequently registers a collision when there is not one, can you check and see if there is anything blatantly wrong with the code? Thanks. I have my own custom vector class, and poly class. normals = self.normals isCollision = [] MTVs = [] for i in other.normals: normals.append(i) for j in normals: selfProj = [] otherProj = [] for k in self.vertices: selfProj.append(j * k) for l in other.vertices: otherProj.append(j * l) minS = min(selfProj) maxS = max(selfProj) minO = min(otherProj) maxO = max(otherProj) if (minS > maxO or minO > maxS): """No collision on THIS axis""" isCollision.append(False) else: isCollision.append(True) MTVmag = min(maxO - minS, maxS - minO) MTV = j * MTVmag MTVs.append(MTV) if (all(x == True for x in isCollision)): vectorMags = [] for m in MTVs: vectorMags.append(m.magSquared) actMTV = MTVs[vectorMags.index(min(vectorMags))] """Finds the MTV with the smallest magnitude""" indexOfNorm = MTVs.index(actMTV) CN = normals[indexOfNorm] """CN = Collision Normal RETURN [CN, 0] for now, the 0 is a placeholder for the collision point""" if(actMTV.y >= 0 and other.pos.y > self.pos.y): self.translate(actMTV * -0.4) other.translate(actMTV * 0.4) return [CN, 0] elif (actMTV.y >= 0 and other.pos.y < self.pos.y): self.translate(actMTV * 0.4) other.translate(actMTV * -0.4) return [CN, 0] elif(actMTV.y <= 0 and other.pos.y > self.pos.y): self.translate(actMTV * 0.4) other.translate(actMTV * -0.4) return [CN, 0] elif (actMTV.y <= 0 and other.pos.y < self.pos.y): self.translate(actMTV * -0.4) other.translate(actMTV * 0.4) return [CN, 0]
  22. I am doing a little physics project with circle circle collisions for now, and have tried to do impulse resolution for collisions with 2 circles, using the following code. relativeVelocity = (other.doVerletVelocity()).subtract(self.doVerletVelocity()) normDirecVel = relativeVelocity.dotProduct(collisionNormal) restitution = -1 - min(self.restitution, other.restitution) numerator = normDirecVel * restitution impulseScalar = numerator / float(1 / self.mass) + float(1 / other.mass) selfVel = self.doVerletVelocity() otherVel = other.doVerletVelocity() impulse = collisionNormal.scalarMult(impulseScalar) selfDV = impulse.scalarMult(1 / self.mass) otherDV = impulse.scalarMult(1 / other.mass) newSelfVel = selfVel.subtract(selfDV) newOtherVel = otherVel.add(otherDV) self.oldPos = (self.center).subtract(newSelfVel.scalarMult(dt)) other.oldPos = (other.center).subtract(newOtherVel.scalarMult(dt)) The problem seems to be that whatever value I give to self.mass and other.mass, the output stays exactly the same, the values that I used are: center = Vector(0, 0) radius = 1 oldPos = Vector(0, 0) accel = Vector(0, 0) mass = 100 restitution = 0.001 center2 = Vector(0, 3.20) radius2 = 1 oldPos2 = Vector(0, 3.201) accel2 = Vector(0, -1) mass2 = 1 restitution2 = 1 the output was: 0.0 0.0 0.0 2.165000000000114 0.0 0.0 0.0 2.1360000000001174 0.0 0.0 0.0 2.1066000000001206 0.0 0.0 0.0 2.076800000000124 0.0 0.0 0.0 2.046600000000127 0.0 0.0 0.0 2.0160000000001306 0.0 0.0 0.0 1.985000000000134 CIRCLE INTERSECTION 0.0 -1.985000000000134 0.0 3.938600000000271 0.0 -3.970000000000268 0.0 5.891800000000408 0.0 -5.9550000000004015 0.0 7.844600000000544 0.0 -7.940000000000535 0.0 9.797000000000681 I changed the values for the masses to make them higher, bu the output still remained the same, if you could get to the bottom of this, it would be much appreciated.
  23. Bob Dylan

    Applying Impulse

    I have a circle class which has the following attributes: center, radius, old position, acceleration, mass, and restitution. I then apply impulse resolution as per this link: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331. Here is the code, implementing that, along with my velocity verlet implementation (this is necessary as it explains why I change the values of the old positions of the circles near the end of the impulseScalar method): def doVerletPosition(self): diffPos = (self.center).subtract(self.oldPos) aggregatePos = diffPos.add(self.center) ATT = (self.accel).scalarMult(dt**2) e = ATT.add(aggregatePos) return e def doVerletVelocity(self): deltaD = ((self.center).subtract(self.oldPos)) return deltaD.scalarMult(1/dt) def impulseScalar(self,other): isCollision = self.collisionDetection(other) collisionNormal = isCollision[0] if(isCollision[1] == True): relativeVelocity = (other.doVerletVelocity()).subtract(self.doVerletVelocity()) normDirecVel = relativeVelocity.dotProduct(collisionNormal) restitution = -1-(min(self.restitution,other.restitution)) numerator = restitution * normDirecVel impulseScalar = numerator/(self.invMass + other.invMass) impulse = collisionNormal.scalarMult(impulseScalar) selfVel = (self.doVerletVelocity()) otherVel = other.doVerletVelocity() selfVelDiff = impulse.scalarMult(self.invMass) otherVelDiff = impulse.scalarMult(other.invMass) selfVel = selfVel.subtract(selfVelDiff) otherVel = otherVel.subtract(otherVelDiff) self.oldPos = (self.center).subtract(selfVel) other.oldPos = (other.center).subtract(otherVel) It would help if you accepted the vector methods as correct on face value, and I think that they are named well enough to allow you to figure out what they do, however I can paste them in aswell. My main problem is that when I run this, it registers that a collision has happened, yet the values position of the second circle do not change. How would I go about fixing this, as it seems that I am implementing the calculations correctly. The values of the first and second circle is: center = Vector(0,0) radius = 3 oldPos = Vector(0,0) accel = Vector(0,0) mass = 1 restitution = 0.5 center2 = Vector(0,4.2) radius2 = 1 oldPos2 = Vector(0,4.21) accel2 = Vector(0,-1) mass2 = 1 restitution2 = 0.7 What it returns is here: (it returns the position of the centers) 0.0 0.0 0.0 4.1896 0.0 0.0 0.0 4.178800000000001 0.0 0.0 0.0 4.167600000000001 0.0 0.0 0.0 4.1560000000000015 0.0 0.0 0.0 4.144000000000002 0.0 0.0 0.0 4.131600000000002 0.0 0.0 0.0 4.118800000000003 0.0 0.0 0.0 4.1056000000000035 0.0 0.0 0.0 4.092000000000004 0.0 0.0 0.0 4.078000000000005 0.0 0.0 0.0 4.063600000000005 0.0 0.0 0.0 4.048800000000006 0.0 0.0 0.0 4.033600000000007 0.0 0.0 0.0 4.018000000000008 0.0 0.0 0.0 4.002000000000009 0.0 0.0 0.0 3.9856000000000096 INTERSECTION 0.0 0.0 0.0 3.9688000000000105 INTERSECTION 0.0 0.0 0.0 3.9516000000000115 INTERSECTION 0.0 0.0 0.0 3.9340000000000126 So when it prints INTERSECTION, surely, the stationary circle must change position, if the impulseScalar method is correct, (as it seems to be (as it follows what is said on that link). Even if I let it run for longer, the stationary circle still does not move.
  24. I wrote Snake in Python 3 using Pygame and was wondering if anyone can do a code review of it? If this is the appropriate fourm to post such a thing? Some things to mention: 1. I realize I could have used a dict in the place of my Segment class, but I decided to go with the class because it looked more clean to me. 2. I used recursion heavily, though I could have used a list instead. I decided to do it recursively for practice and fun (I don't use recursion often). 3. I don't have doc strings for any of my functions. 4. I probably could have used my get_all_snake_segment_locations function to avoid recursion. 5. I set fps to 10 to limit the speed of the game. Is this a bad way to do such a thing? 6. I attached an input manager I created and unit tests for my game for completeness. Though, I'm only asking the actual game to be reviewed, if you want to look at those you can. Also, note the unit tests are not complete yet for several functions I changed. 7. I really appreciate anyone who takes the time to give me feedback of any kind. This fourm has been a huge help to me and I'm grateful for everyone's insight! import sys import random import itertools import pygame import inputmanager class Segment: def __init__(self, rect, direction=None, parent=None, child=None): self.rect = rect self.direction = direction self.parent = parent self.child = child class Game: def __init__(self): pygame.init() self.fps_clock = pygame.time.Clock() self.fps = 10 self.window_size = (640, 480) self.displaysurf = pygame.display.set_mode(self.window_size) pygame.display.set_caption("Snake") self.cell_size = (32, 32) self.start_location = (320, 224) self.head_segment = Segment(pygame.Rect(self.start_location, self.cell_size)) self.up = "up" self.down = "down" self.left = "left" self.right = "right" self.black = (0, 0, 0) self.green = (0, 255, 0) self.red = (255, 0, 0) self.direction = None self.extender = None self.cell_locations = set( itertools.product( range(0, self.window_size[0], self.cell_size[0]), range(0, self.window_size[1], self.cell_size[1]) ) ) def main(self): while True: self.get_input() self.update() self.render() self.fps_clock.tick(self.fps) def get_input(self): inputmanager.InputManager.get_events() inputmanager.InputManager.check_for_quit_event() inputmanager.InputManager.update_keyboard_key_state() inputmanager.InputManager.get_keyboard_input() def update(self): self.handle_input() self.update_snake_direction(self.head_segment, self.direction) self.move_snake(self.head_segment) if self.extender is None: self.add_extender_to_board() if self.head_segment_collided_with_extender(): self.extend_snake() if self.game_over(): self.refresh() def handle_input(self): if inputmanager.InputManager.quit: self.terminate() if (inputmanager.InputManager.keyboard[pygame.K_UP] == inputmanager.InputManager.pressed and self.direction != self.down): self.direction = self.up elif (inputmanager.InputManager.keyboard[pygame.K_DOWN] == inputmanager.InputManager.pressed and self.direction != self.up): self.direction = self.down elif (inputmanager.InputManager.keyboard[pygame.K_LEFT] == inputmanager.InputManager.pressed and self.direction != self.right): self.direction = self.left elif (inputmanager.InputManager.keyboard[pygame.K_RIGHT] == inputmanager.InputManager.pressed and self.direction != self.left): self.direction = self.right def terminate(self): pygame.quit() sys.exit() def update_snake_direction(self, segment, parent_direction): ###TEST if segment.child is not None: self.update_snake_direction(segment.child, parent_direction) if segment.parent is None: segment.direction = parent_direction else: segment.direction = segment.parent.direction def move_snake(self, segment): self.move_segment(segment) if segment.child is not None: self.move_snake(segment.child) def move_segment(self, segment): if segment.direction == self.up: segment.rect.move_ip(0, -self.cell_size[1]) elif segment.direction == self.down: segment.rect.move_ip(0, self.cell_size[1]) elif segment.direction == self.left: segment.rect.move_ip(-self.cell_size[0], 0) elif segment.direction == self.right: segment.rect.move_ip(self.cell_size[0], 0) def add_extender_to_board(self): snake_segments_locations = set(self.get_all_snake_segment_locations(self.head_segment)) location = random.choice(list(self.cell_locations-snake_segments_locations)) self.extender = pygame.Rect(location, self.cell_size) def get_all_snake_segment_locations(self, segment): yield segment.rect.topleft if segment.child is not None: yield from self.get_all_snake_segment_locations(segment.child) def head_segment_collided_with_extender(self): return self.head_segment.rect.colliderect(self.extender) def extend_snake(self): self.extender = None self.add_segment_to_snake(self.head_segment) def add_segment_to_snake(self, segment): if segment.child is None: if segment.direction == self.up: topleft = (segment.rect.x, segment.rect.y+self.cell_size[1]) elif segment.direction == self.down: topleft = (segment.rect.x, segment.rect.y-self.cell_size[1]) elif segment.direction == self.left: topleft = (segment.rect.x+self.cell_size[0], segment.rect.y) elif segment.direction == self.right: topleft = (segment.rect.x-self.cell_size[0], segment.rect.y) segment.child = Segment( pygame.Rect(topleft, self.cell_size), segment.direction, segment ) else: self.add_segment_to_snake(segment.child) def game_over(self): return any([ self.head_segment_collided_with_self(self.head_segment), self.head_segment_out_of_bounds() ]) def head_segment_collided_with_self(self, segment): if segment.child is not None: if self.head_segment.rect.colliderect(segment.child.rect): return True else: return self.head_segment_collided_with_self(segment.child) return False def head_segment_out_of_bounds(self): if (self.head_segment.rect.x < 0 or self.head_segment.rect.y < 0 or self.head_segment.rect.x >= self.window_size[0] or self.head_segment.rect.y >= self.window_size[1]): return True return False def refresh(self): self.head_segment = Segment(pygame.Rect(self.start_location, self.cell_size)) self.direction = None self.extender = None def render(self): self.displaysurf.fill(self.black) self.draw_snake(self.head_segment) if self.extender is not None: self.draw_extender() pygame.display.update() def draw_snake(self, segment): pygame.draw.rect(self.displaysurf, self.green, segment.rect) if segment.child is not None: self.draw_snake(segment.child) def draw_extender(self): pygame.draw.rect(self.displaysurf, self.red, self.extender) if __name__ == "__main__": game = Game() game.main() test_game.py inputmanager.py game.py
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!