Jump to content
  • Advertisement

mrpeed

Member
  • Content Count

    41
  • Joined

  • Last visited

Community Reputation

278 Neutral

About mrpeed

  • Rank
    Member

Personal Information

  • Interests
    Art
    Audio
    Design
    Programming
    QA

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. mrpeed

    shooting bullets

    I found this tutorial helpful. http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/
  2. You will probably need a unique use_item function for each item if the behavior is unique for each. I don't code in C++ but perhaps you could create separate use_item functions and pass them as an argument upon object creation? Ex in Python: class UseableItem(InventoryItem): def __init__(self, use_item_function): self.use_item_function = use_item_function health_potion = UseableItem(use_health_potion_function) So you would use pointers to functions I guess? Basically, you would have one UseableItem class that can receive a use_item function upon creation. And perhaps you could pass parameters to the function you send UseableItem upon creation as well so you don't need separate functions for lets say different levels of a health potion. Note again I'm a Python developer and I don't have experience with Cry Engine so I'm just providing whatever insight I can. Basically, if you can change the use_item function into an argument the UseableItem can receive upon creation than you can avoid lots of duplication of code. Please let me know if I was clear or if I did not understand your question correctly. Or if anyone thinks this is a bad approach...
  3. Does anyone have any recommendations for good books on game engine design for 2D games that a beginner would comprehend? I'm not looking for something pertaining to a specific language or anything, but something that will give me a good understanding of game engines in general that I can then apply to my own projects. Basically, I'm self taught up to this point and would like to expand my knowledge. Thanks.
  4. mrpeed

    How Much is Too Much?

    Too much is too much when you are unhappy and not enjoying yourself. Sometimes, we like the idea of doing things but not actually doing them. If you find that doing all those different things is making you unhappy, than you should reconsider how you spend your time. But if you genuinely enjoy what you do, then by all means keep doing it. Well first, if you are talking about improvement you need to make sure you are practicing properly and that you are applying what you practice to actual projects. You can spend lots of time doing things and not get any better because you aren't challenging yourself properly. Also, you can evenly divide your time among the different skills you mentioned to make sure you aren't "suffering" in any area. But as your life gets more busy you will find that you may not have lots of time in a day, and doing everything may no longer be viable. In that case you should probably decide on which skills are more important to you and focus on those. If you focus on everything you may never master one thing, but that may be okay if that's not a goal for you.
  5. mrpeed

    Python code review for Snake

    I did a second draft of the game.py file if you want to take a look. I plan to redo my input manager this week. Some questions: 1. I use lots of functions because I find reading something like draw_segment() easier than reading pygame.draw.rect(self.displaysurf, GREEN, segment.rect), even if the function is one line. Also, I find that smaller functions are easy to write tests for which I often do. And if I need to make a change in the future, I would know exactly where a change needs to go. Do you think that approach is overkill for this program or in general? 2. Do you think putting all of my methods in the Game class for a game of this size is bad? Again thanks for taking your time to look at my game! It has been super helpful. #Removed refresh(), terminate(), extend_snake(), draw_extender(), draw_snake() #Capitalized constants #Added spaces #Modified some methods #Now uses lists import sys import random import itertools import pygame import inputmanager FPS = 10 WINDOW_SIZE = (640, 480) CELL_SIZE = (32, 32) START_LOCATION = (320, 224) UP = "up" DOWN = "down" LEFT = "left" RIGHT = "right" BLACK = (0, 0, 0) GREEN = (0, 255, 0) RED = (255, 0, 0) class Segment: def __init__(self, rect, direction=None): self.rect = rect self.direction = direction class Game: def __init__(self): self.direction = None self.extender = None self.cell_locations = self.cell_locations = set( itertools.product( range(0, WINDOW_SIZE[0], CELL_SIZE[0]), range(0, WINDOW_SIZE[1], CELL_SIZE[1]) ) ) self.snake = [Segment(pygame.Rect(START_LOCATION, CELL_SIZE))] pygame.init() self.fps_clock = pygame.time.Clock() self.displaysurf = pygame.display.set_mode(WINDOW_SIZE) pygame.display.set_caption("Snake") def main(self): while True: self.get_input() self.update() self.render() self.fps_clock.tick(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.direction) self.move_snake() if self.extender is None: snake_segments_locations = set(segment.rect.topleft for segment in self.snake) location = random.choice(list(self.cell_locations-snake_segments_locations)) ###Need to use set to subtract, and need to convert to list to use random.choice self.extender = pygame.Rect(location, CELL_SIZE) if self.head_segment_collided_with_extender(): self.extender = None self.add_segment_to_snake() if self.game_over(): self.snake = [Segment(pygame.Rect(START_LOCATION, CELL_SIZE))] self.direction = None self.extender = None def handle_input(self): if inputmanager.InputManager.quit: pygame.quit() sys.exit() if (inputmanager.InputManager.keyboard[pygame.K_UP] == inputmanager.InputManager.pressed and self.direction != DOWN): self.direction = UP elif (inputmanager.InputManager.keyboard[pygame.K_DOWN] == inputmanager.InputManager.pressed and self.direction != UP): self.direction = DOWN elif (inputmanager.InputManager.keyboard[pygame.K_LEFT] == inputmanager.InputManager.pressed and self.direction != RIGHT): self.direction = LEFT elif (inputmanager.InputManager.keyboard[pygame.K_RIGHT] == inputmanager.InputManager.pressed and self.direction != LEFT): self.direction = RIGHT def update_snake_direction(self, head_direction): for index in reversed(range(len(self.snake))): self.snake[index].direction = self.snake[index-1].direction self.snake[0].direction = head_direction def move_snake(self): for segment in self.snake: self.move_segment(segment) def move_segment(self, segment): move_amount = { UP: (0, -CELL_SIZE[1]), DOWN: (0, CELL_SIZE[1]), LEFT: (-CELL_SIZE[0], 0), RIGHT: (CELL_SIZE[0], 0) }.get(segment.direction, (0, 0)) segment.rect.move_ip(move_amount) def head_segment_collided_with_extender(self): return self.snake[0].rect.colliderect(self.extender) def add_segment_to_snake(self): topleft = { UP: (self.snake[-1].rect.x, self.snake[-1].rect.y+CELL_SIZE[1]), DOWN: (self.snake[-1].rect.x, self.snake[-1].rect.y-CELL_SIZE[1]), LEFT: (self.snake[-1].rect.x+CELL_SIZE[0], self.snake[-1].rect.y), RIGHT: (self.snake[-1].rect.x-CELL_SIZE[0], self.snake[-1].rect.y) }.get(self.snake[-1].direction, (0, 0)) self.snake.append(Segment(pygame.Rect(topleft, CELL_SIZE), self.snake[-1].direction)) def game_over(self): return (self.head_segment_collided_with_self() or self.head_segment_out_of_bounds()) def head_segment_collided_with_self(self): return any([self.snake[0].rect.colliderect(segment) for segment in self.snake[1:]]) def head_segment_out_of_bounds(self): return (self.snake[0].rect.x < 0 or self.snake[0].rect.y < 0 or self.snake[0].rect.x >= WINDOW_SIZE[0] or self.snake[0].rect.y >= WINDOW_SIZE[1]) def render(self): self.displaysurf.fill(BLACK) for segment in self.snake: pygame.draw.rect(self.displaysurf, GREEN, segment.rect) if self.extender is not None: pygame.draw.rect(self.displaysurf, RED, self.extender) pygame.display.update() if __name__ == "__main__": game = Game() game.main() @Alberth game.py
  6. mrpeed

    Python code review for Snake

    Thanks so much for the reply, I'm going to review your comments and I'll get back with any additional questions.
  7. 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
  8. Lets say I have a character with a shooting animation that plays every time I hit the space key. I need to block input to assure that the animation finishes before another action is taken. What is a common approach to doing this? Right now, I'm using a variable that is a set to the total number of seconds the animation is. When the variable is zero player input is allowed again. Is there a better way? I'm using Python and Pygame for a 2D game.
  9. Currently, I'm working on recreating connect four for a portfolio of simple games. I'm also writing unit tests for all the code I can. Some of my code functions though only call other functions, or only draw to the screen... #EXAMPLES... def draw_refresh_button_text(self): font = pygame.font.Font(None, 24) text = font.render("Refresh", True, self.black) self.displaysurf.blit( text, ( self.refresh_button_rect.centerx-self.refresh_button_rect.centerx/self.refresh_button_rect.y, self.refresh_button_rect.centery-self.refresh_button_rect.centery/self.refresh_button_rect.x ) ) def draw_disks(self): for column in self.grid: for disk in column: pygame.draw.ellipse(self.displaysurf, disk['color'], disk['rect']) #ONLY CALLS OTHER FUNCTIONS... 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() inputmanager.InputManager.update_mouse_button_state() inputmanager.InputManager.get_mouse_input() How would I go about writing tests for code like this? Should code like this even be tested? Should all code be tested? I'm using the Python unittest module to test. The code here uses Pygame.
  10. Is redrawing the entire screen every frame the common approach? Even if there are areas on the display that haven't changed? I'm using Pygame and I've read that you should only redraw the area of the screen that has been changed for performance reasons, though I'm not sure if this is unique to Pygame or even relevant to to Pygame anymore.
  11. Though not from Mapt/Packt, this is a good book to give a read (free online!). http://gameprogrammingpatterns.com/contents.html
  12. This function detects if a gameobject has moved or has had its sprite changed. It then calls one of two functions (or none), to draw a piece of the games background over the gameobjects current location or previous location. Should functions like this be avoided? Is this good or bad design? Does it violate SRP? Also, how would something like this be unit tested? #clean up the display... def blit_background_over_dirty_rects(self): for gameobject, data in self.relevant_data.items(): if data['location'] != gameobject.rect.topleft: #gameobject moved... self._blit_background_over_gameobjects_previous_location(gameobject) elif data['sprite'] != gameobject.sprite_manager.current_sprite: #gameobjects sprite changed... self._blit_background_over_gameobjects_current_location(gameobject)
  13. If I see no reason for something to be a property over a method should I favor making it a property or a method? For example, I can see no benefit in doing a "full" property over a "is_full() method", other than not having to write (). I can understand if full started as a regular variable and was expanded to a property later, but it wasn't. So in that case what would you say?
  14. Yes, I am initializing that in the __init__ method. And makes sense, I decided to remove the is_full() check from each method and have the inventory size enforced outside of the inventory class. This also removed a lot of clutter from my methods which is good. I was wondering if you can clarify when to use properties? I tend to avoid them because I feel like they are misleading. For example, @property def full(self): return len(self.items) >= self.max_inventory_size Doesn't this hide the fact that this is a method? Would a user not think this a regular variable and possibly try to assign to it? I have other methods labeled get and set throughout my code base that changes behavior within different classes. Would it be misleading to convert those to properties? Another example, would it be to misleading to make this a next_sprite property? def get_next_sprite(self): if self.current_count == self.max_count: #Time to switch sprites... self.current_count = 0 self.current_sprite = next(self.sprite_reel) else: #Increment and return the same sprite from last frame... self.current_count += 1 return self.current_sprite
  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!