Jump to content
  • Advertisement

Search the Community

Showing results for tags 'Python'.



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 Dev Loadout
  • Game Dev Unchained

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

  • 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


Role


Twitter


Github


Twitch


Steam

Found 45 results

  1. 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:
  2. Hello all, essentially what I'm looking for is a flowchart generator that I can leverage with my python applications using, "magic characters" (@) and the like, above flow control structures, and important bits of code. While there does seem to exist some similar libraries in the py eco system, there doesn't seem to be anything 1:1 to what I'm looking for, I've heard of Doxygen, but i'd prefer something native to Python. Really just something that gives my engineers minimal control of the output of what the flowchart will look like in the most minimally invasive way possible. Also, I know the process for flowcharting is backwards in this proposition, but this is more for management after the fact. If something exists, great! If not, I'll code it out, but don't want to duplicate efforts if something similar is already out there Marcus
  3. Hello I am trying to create a grid of images in pyglet and python and I am not sure where exactly I am going wrong. The goal is for it to be a Breakout/Arkanoid clone. The problem I am having is getting the brick images to display in a grid. Here is the code that as far as I can tell, should place the bricks in the correct position. class Brick(): def __init__(self, space): # Create the list to hold different sprite bricks and load images self.batch = pyglet.graphics.Batch() self.brick_images = ['brick1.png', 'brick2.png'] self.brick_sprites = [] # 1 out of 5 chance to drop a power pill self.chance_to_drop = 1 # Set the images anchor point to its center and create sprites for i in range(len(self.brick_images)): img = pyglet.image.load(self.brick_images[i]) img.anchor_x = img.width // 2 img.anchor_y = img.height // 2 self.brick_sprites.append(pyglet.sprite.Sprite(img)) for x in range(7): for y in range(7): self.body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) # The position where each pymunk body will be placed self.body.position = x * 100 + 75, y * 30 + 340 self.brick_type = random.randint(0, len(self.brick_sprites) - 1) if self.brick_type == 0: sprite = self.brick_sprites[0] # Set the sprite to the same position as the pymunk body sprite.set_position(self.body.position.x, self.body.position.y) sprite.batch = self.batch elif self.brick_type == 1: sprite = self.brick_sprites[1] sprite.set_position(self.body.position.x, self.body.position.y) sprite.batch = self.batch self.shape = pymunk.Segment(self.body, (0, 0), (50, 0), 6) self.shape.elasticity = 0.80 self.shape.collision_type = collision_types['brick'] space.add(self.body, self.shape) handler = space.add_collision_handler(collision_types['brick'], collision_types['ball']) handler.separate = self.remove_brick So what I am trying to accomplish is have 7 rows of 7 bricks. As far as I can see the sprites are being created in the loop, but when I run the program only 2 bricks are being displayed. I am sure there is something wrong with the way I am looping but honestly just cannot see where I am going wrong. I have spent some time, trying to see the error but simply cannot see where I am going wrong. I can see that the pyglet brick sprites are NOT being set to the correct x, y of the pymunk body, even though, using the same formula for the player paddle object lines up the sprite perfectly. #Set the sprite to pymunk object position self.image = pyglet.image.load('paddle.png') self.image.anchor_x = self.image.width // 2 self.image.anchor_y = self.image.height // 2 self.sprite = pyglet.sprite.Sprite(self.image, x=self.position.x, y=self.position.y) I am very confused with this one and I just hope I have explained everything clearly enough. Thank you for any help or assistance in any way.
  4. Hi, I have an online multiplayer RPG maze game which I built in NodeJS. It is quite simple. Uses socket.io. Single threaded application so I don't have to worry about race conditions such as two users attempting to take the same object at the same time. The client sends in messages, which are processed by the gameserver and alter the player/world state, query the MySQL database, and broadcasting messages to all the other players and also updating things in the MySQL database. In the last month I have been learning python and I would like to port my game to Python as I think it will be better suited. Doing some research I have found many suggest using Twisted Python so this is the route I am going to take. I wondered if anyone could give me some suggestions for a basic framework of how I would handle the problem of race conditions when moving to an environment where things are operating in parallel, especially with regard the querying and updating of the state in the MySQL. If at all possible I wondered if there are any open source implementations of an MMO architecture using Twisted Python that I could look through that dealt with these issues. Thank you for your time reading this
  5. I want to make some games. My question is what should my first steps be, besides learning more python and unity2d? I'm hoping I haven't asked this before. I thought my first step was conquering enough of unity and python so I can start making small games. I don't know enough python to build a text-based adventure game just yet. I haven't really started with unity 2d yet. I want to make 4 games: 1) a survival game set in a bubble in New Zealand 2) an rpg battle game about differently-shaped spaceships protecting their resources 3) a hustling game influenced by land of Illusion: starring mickey mouse graphics and hell's kitchen ds mechanics 4) an end of the world game where you play god and mutate heroes to fight the ultimate evil supervillain Other games which are major influences include: 8bitMMO, Another World, Discworld 2, Clop, Osmos, Hacker Evolution: Untold, the sims 1, close combat 1, MTGO, Limbo, Doug TenNapel games, Lemmings, Freedom Force, Gain Ground, Gynoug, Joust, Robocop Vs The Terminator, Ecco: the Dolphin, Super Meat Boy and Syphon Filter 1. Also does anyone have tips about marketing, or should I not worry until I have an early build?
  6. WinterDragon

    time in loop

    I'm trying to find/figure out where in a loop, before the loop, after the loop, the computer understands time. As I have created a loop and I need to put a time-limit on an input. lost my program, so I'll adapt the following to a guessing game from a coin flip. Then I need to insert a time counter, just need to understand where to put it? import random def variables (): heads = 0 tails = 0 coinCount = 0 againPlay = "y" def game(): heads = 0 tails = 0 againPlay = "y" coinCount = 1 while coinCount > 0: if againPlay != "y": print ("you had ", heads, "heads.") print (" and ", tails, "tails.") end = input ("You're all done now!") nmCoin = random.randrange(2) if coinCount > 100: againPlay = "n" if nmCoin == 1: heads = heads + 1 coinCount = coinCount + 1 elif nmCoin == 0: tails = tails + 1 coinCount = coinCount + 1 else: print ("you had ", heads, "heads.") print (" and ", tails, "tails.") end = input ("You're all done now!") variables () game ()
  7. I've been trying different algorithms, and just yesterday I adapted one from the Graphics Programmer's Black Book (the chapter 17), and it works... but doesn't wrap around the edges like the other algorithms do. It does vertically, but not horizontally. I'm doing the wrapping by using an extra outer border of cells all around, that each gets a copy of the opposite inner border. I've been trying for hours to figure out why it isn't wrapping around but I got nowhere so far. Meanwhile I also burned out. If someone else could take a look and see if they could figure out what's wrong, I'd appreciate it a lot. A fresh pair of eyes might see better than mine. I don't know if I should paste the code right here, as it's a little long (some 200 lines), so meanwhile it's in this repo right here. It's a simple console app, works on the windows console (don't know about the linux terminal). There's two generation algorithms there for comparison, and you can easily switch using the algo variable. The SUM works fine, the BITS is the one that doesn't. Not sure what else to say. I tried commenting the code for clarity. Well, if someone has 5 minutes to spare, I'll greatly appreciate it. Thanks in advance. ---------- EDIT: A specific symptom that I noticed (that I didn't think to mention earlier) is that when using the BITS algorithm (which uses bit manipulation, hence the name of the flag), the cells on the outter edges don't seem to be affected by this part of the code that kills a cell or the equivalent part to revive a cell (specifically the "[i-1]" and "[i+1]" lines, which should affect the cells to the sides of the cell being considered): # if it's alive if cellmaps[prev][j][i] & 0x01: # kill it if it doesn't have 2 or 3 neighbors if (n != 2) and (n != 3): cellmaps[curr][j][i] &= ~0x01 alive_cells -= 1 # inform neighbors this cell is dead cellmaps[curr][ j-1 ][ i-1 ] -= 2 cellmaps[curr][ j-1 ][ i ] -= 2 cellmaps[curr][ j-1 ][ i+1 ] -= 2 cellmaps[curr][ j ][ i-1 ] -= 2 cellmaps[curr][ j ][ i+1 ] -= 2 cellmaps[curr][ j+1 ][ i-1 ] -= 2 cellmaps[curr][ j+1 ][ i ] -= 2 cellmaps[curr][ j+1 ][ i+1 ] -= 2 The actual effect is that the leftmost and rightmost edges are always clear (actually, as depicted, the ones on the opposite side to where the actual glider is, are affected, but not the ones next to the glider). when a glider approaches the edge, for exampple, this edge should have 1 cell And the opposite side should v like this not be like this, but this V v V V | . . . . | . . . . . . . .| . . . .| | . . # . | . . # . . . . .| . . . .| | . # . . | # # . . . . . #| . . # #| | . # # . | . # # . . . . #| . . . #| | . . . . | . . . . . . . .| . . . .| | . . . . | . . . . . . . .| . . . .|
  8. So I used python 3 for ios on my ipad to do part one of this assignment. Part One: create a guess my number game: numSpecial = 0 time = 0 guesses = 0 g = 0 i = 0 import random numSpecial= random.randint(1,9) print ("guess my nmber, biatch! between 1 and 10") while g!= numSpecial: time = time + 1 if time > 5: print ("you took too long, loser") elif g > numSpecial: print ("too high, shithead") guesses = guesses + 1 elif g < numSpecial: print ("too low, asshole") guesses = guesses + 1 elif guesses > 10: print ("I have had enough of your shit") else: print ("you found an error") g = int(input("what is your guess?")) if g == numSpecial: print ("you guessed right, you are not as stupid as I thought.") i = input () Part Two: figure out where in the program the computer recognises time and place a time limit on the game. And no it doesn't have an ending because I haven't covered ending a program in the text yet.
  9. 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
  10. 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
  11. 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.
  12. 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.
  13. My first goal is to build in python a text-based (next version will have graphics) adventure game scenario where a player enters a tavern, and goes on a quest. Earns money, buys weapons and gets in a fight. So I've got four ideas for games I want to build. 1. a space simulation where a mute evolving clique is tasked with colonising planets - it's also a social network. My next goal is to build a 3rd person shooter and streets of rage style framework for a action/adventure game based on my story which is about God's mightiest heroes (with mutation sandbox) versus the devil (read pinhead meets bizarro superman). I also want to build in python, a 3d isometric rpg/sim that looks like the sims 1 but thematically is more like Bully or GTA1, but plays like Hell's Kitchen DS combined with Dofus, with environments combining elements of Phantasy Star, Sonic and art photography of convenience stores, etc. I also want to build an epic adventure story in RPGMakerMV. Any advice as to what else I should build in between to get closer to my goal projects. In a few weeks I'll have my first game, I'm not really sure how to turn it into an executable file so i can share it with people who don't have python installed.
  14. Tazbird

    Projectile Dominion: Ending Screen

    From the album: MissileCommandChallenge2018

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

    Projectile Dominion: Title Screen

    From the album: MissileCommandChallenge2018

    The title screen to my 2018 Missile Command Challenge submission
  16. 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.
  17. 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 ()
  18. 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.
  19. 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 ()
  20. 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.
  21. Hi, how are you, people who love programming, here I am again after a very long time, I returned to Blender again with my project that I had left aside for personal study, work, etc. This time I want to resort to the help of Python programming experts and GLSL in Blender Game Engine. The first question is? How to make FOG OF WAR in GLSL and Python to a RTS GAME. I am developing an RTS game in UPBGE or BGE. Only I want make a Fog of War System like the game Age of Empires. Do you remember? jajaja Ok Brothers. Everything you konw please help me. I'll be very greatful I will leave pictures of the game I am developing. Regards guys!! https://ibb.co/dyQBPv
  22. 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()
  23. 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]
  24. Hello! I am currently a student at Aberystwyth University between my 2nd and 3rd years of my BSc in Computer Science. I am currently on an internship year where I am working at Google in London. I've always had an interest in game development and it's something I would very much like to go into once I graduate. I am most proficient in Java and Python, but am also currently learning C++ and Go. I can also do JavaScript and SQL and have experience in using SVN and Git for version control. In terms of game dev experience I have little other than a group project worth 75% of a module for my second year at university where I achieved the highest classification. For the engines I am familiar with I am learning Unity with a view as to learn Unreal at some point in the near future when I feel I have become very competent with Unity. Other than my programming skills I am also able to perform QA and basic business operations for products. I would also consider myself approachable and easy to talk with. I am looking for any kinds of projects currently just to get some experience in game development and am willing to answer any questions that you might have relating to myself or my skills. Thanks in advance, Liam
  • 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!