Created
December 19, 2012 15:32
-
-
Save vinothpandian/4337527 to your computer and use it in GitHub Desktop.
Classic Pong game in Python - using pygame
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #PONG pygame | |
| import random | |
| import pygame, sys | |
| from pygame.locals import * | |
| pygame.init() | |
| fps = pygame.time.Clock() | |
| #colors | |
| WHITE = (255,255,255) | |
| RED = (255,0,0) | |
| GREEN = (0,255,0) | |
| BLACK = (0,0,0) | |
| #globals | |
| WIDTH = 600 | |
| HEIGHT = 400 | |
| BALL_RADIUS = 20 | |
| PAD_WIDTH = 8 | |
| PAD_HEIGHT = 80 | |
| HALF_PAD_WIDTH = PAD_WIDTH / 2 | |
| HALF_PAD_HEIGHT = PAD_HEIGHT / 2 | |
| ball_pos = [0,0] | |
| ball_vel = [0,0] | |
| paddle1_vel = 0 | |
| paddle2_vel = 0 | |
| l_score = 0 | |
| r_score = 0 | |
| #canvas declaration | |
| window = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32) | |
| pygame.display.set_caption('Hello World') | |
| # helper function that spawns a ball, returns a position vector and a velocity vector | |
| # if right is True, spawn to the right, else spawn to the left | |
| def ball_init(right): | |
| global ball_pos, ball_vel # these are vectors stored as lists | |
| ball_pos = [WIDTH/2,HEIGHT/2] | |
| horz = random.randrange(2,4) | |
| vert = random.randrange(1,3) | |
| if right == False: | |
| horz = - horz | |
| ball_vel = [horz,-vert] | |
| # define event handlers | |
| def init(): | |
| global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel,l_score,r_score # these are floats | |
| global score1, score2 # these are ints | |
| paddle1_pos = [HALF_PAD_WIDTH - 1,HEIGHT/2] | |
| paddle2_pos = [WIDTH +1 - HALF_PAD_WIDTH,HEIGHT/2] | |
| l_score = 0 | |
| r_score = 0 | |
| if random.randrange(0,2) == 0: | |
| ball_init(True) | |
| else: | |
| ball_init(False) | |
| #draw function of canvas | |
| def draw(canvas): | |
| global paddle1_pos, paddle2_pos, ball_pos, ball_vel, l_score, r_score | |
| canvas.fill(BLACK) | |
| pygame.draw.line(canvas, WHITE, [WIDTH / 2, 0],[WIDTH / 2, HEIGHT], 1) | |
| pygame.draw.line(canvas, WHITE, [PAD_WIDTH, 0],[PAD_WIDTH, HEIGHT], 1) | |
| pygame.draw.line(canvas, WHITE, [WIDTH - PAD_WIDTH, 0],[WIDTH - PAD_WIDTH, HEIGHT], 1) | |
| pygame.draw.circle(canvas, WHITE, [WIDTH//2, HEIGHT//2], 70, 1) | |
| # update paddle's vertical position, keep paddle on the screen | |
| if paddle1_pos[1] > HALF_PAD_HEIGHT and paddle1_pos[1] < HEIGHT - HALF_PAD_HEIGHT: | |
| paddle1_pos[1] += paddle1_vel | |
| elif paddle1_pos[1] == HALF_PAD_HEIGHT and paddle1_vel > 0: | |
| paddle1_pos[1] += paddle1_vel | |
| elif paddle1_pos[1] == HEIGHT - HALF_PAD_HEIGHT and paddle1_vel < 0: | |
| paddle1_pos[1] += paddle1_vel | |
| if paddle2_pos[1] > HALF_PAD_HEIGHT and paddle2_pos[1] < HEIGHT - HALF_PAD_HEIGHT: | |
| paddle2_pos[1] += paddle2_vel | |
| elif paddle2_pos[1] == HALF_PAD_HEIGHT and paddle2_vel > 0: | |
| paddle2_pos[1] += paddle2_vel | |
| elif paddle2_pos[1] == HEIGHT - HALF_PAD_HEIGHT and paddle2_vel < 0: | |
| paddle2_pos[1] += paddle2_vel | |
| #update ball | |
| ball_pos[0] += int(ball_vel[0]) | |
| ball_pos[1] += int(ball_vel[1]) | |
| #draw paddles and ball | |
| pygame.draw.circle(canvas, RED, ball_pos, 20, 0) | |
| pygame.draw.polygon(canvas, GREEN, [[paddle1_pos[0] - HALF_PAD_WIDTH, paddle1_pos[1] - HALF_PAD_HEIGHT], [paddle1_pos[0] - HALF_PAD_WIDTH, paddle1_pos[1] + HALF_PAD_HEIGHT], [paddle1_pos[0] + HALF_PAD_WIDTH, paddle1_pos[1] + HALF_PAD_HEIGHT], [paddle1_pos[0] + HALF_PAD_WIDTH, paddle1_pos[1] - HALF_PAD_HEIGHT]], 0) | |
| pygame.draw.polygon(canvas, GREEN, [[paddle2_pos[0] - HALF_PAD_WIDTH, paddle2_pos[1] - HALF_PAD_HEIGHT], [paddle2_pos[0] - HALF_PAD_WIDTH, paddle2_pos[1] + HALF_PAD_HEIGHT], [paddle2_pos[0] + HALF_PAD_WIDTH, paddle2_pos[1] + HALF_PAD_HEIGHT], [paddle2_pos[0] + HALF_PAD_WIDTH, paddle2_pos[1] - HALF_PAD_HEIGHT]], 0) | |
| #ball collision check on top and bottom walls | |
| if int(ball_pos[1]) <= BALL_RADIUS: | |
| ball_vel[1] = - ball_vel[1] | |
| if int(ball_pos[1]) >= HEIGHT + 1 - BALL_RADIUS: | |
| ball_vel[1] = -ball_vel[1] | |
| #ball collison check on gutters or paddles | |
| if int(ball_pos[0]) <= BALL_RADIUS + PAD_WIDTH and int(ball_pos[1]) in range(paddle1_pos[1] - HALF_PAD_HEIGHT,paddle1_pos[1] + HALF_PAD_HEIGHT,1): | |
| ball_vel[0] = -ball_vel[0] | |
| ball_vel[0] *= 1.1 | |
| ball_vel[1] *= 1.1 | |
| elif int(ball_pos[0]) <= BALL_RADIUS + PAD_WIDTH: | |
| r_score += 1 | |
| ball_init(True) | |
| if int(ball_pos[0]) >= WIDTH + 1 - BALL_RADIUS - PAD_WIDTH and int(ball_pos[1]) in range(paddle2_pos[1] - HALF_PAD_HEIGHT,paddle2_pos[1] + HALF_PAD_HEIGHT,1): | |
| ball_vel[0] = -ball_vel[0] | |
| ball_vel[0] *= 1.1 | |
| ball_vel[1] *= 1.1 | |
| elif int(ball_pos[0]) >= WIDTH + 1 - BALL_RADIUS - PAD_WIDTH: | |
| l_score += 1 | |
| ball_init(False) | |
| #update scores | |
| myfont1 = pygame.font.SysFont("Comic Sans MS", 20) | |
| label1 = myfont1.render("Score "+str(l_score), 1, (255,255,0)) | |
| canvas.blit(label1, (50,20)) | |
| myfont2 = pygame.font.SysFont("Comic Sans MS", 20) | |
| label2 = myfont2.render("Score "+str(r_score), 1, (255,255,0)) | |
| canvas.blit(label2, (470, 20)) | |
| #keydown handler | |
| def keydown(event): | |
| global paddle1_vel, paddle2_vel | |
| if event.key == K_UP: | |
| paddle2_vel = -8 | |
| elif event.key == K_DOWN: | |
| paddle2_vel = 8 | |
| elif event.key == K_w: | |
| paddle1_vel = -8 | |
| elif event.key == K_s: | |
| paddle1_vel = 8 | |
| #keyup handler | |
| def keyup(event): | |
| global paddle1_vel, paddle2_vel | |
| if event.key in (K_w, K_s): | |
| paddle1_vel = 0 | |
| elif event.key in (K_UP, K_DOWN): | |
| paddle2_vel = 0 | |
| init() | |
| #game loop | |
| while True: | |
| draw(window) | |
| for event in pygame.event.get(): | |
| if event.type == KEYDOWN: | |
| keydown(event) | |
| elif event.type == KEYUP: | |
| keyup(event) | |
| elif event.type == QUIT: | |
| pygame.quit() | |
| sys.exit() | |
| pygame.display.update() | |
| fps.tick(60) |
Nice and Simple code. Just one feedback. Please update all the lines having / to // as python 3 does not give back Integer with normal division symbol if the variables being used are not integer. hence creating a Type Error. for example:
ball_pos = [WIDTH/2,HEIGHT/2] to ball_pos = [WIDTH//2,HEIGHT//2]
Otherwise users will get TypeError: integer argument expected, got float Rest is perfect.
Worked like a charm! Or should I say PyCharm?! >:-}
Open World Action Adventure Game (Three.js)
Project Structure
open-world-game/
│
├── index.html
├── style.css
├── package.json
├── README.md
│
├── /assets
│ ├── /textures
│ ├── /models
│ ├── /sounds
│ └── /images
│
├── /js
│ ├── main.js
│ ├── player.js
│ ├── world.js
│ ├── enemy.js
│ ├── vehicle.js
│ ├── ui.js
│ ├── controls.js
│ ├── weather.js
│ ├── inventory.js
│ ├── missions.js
│ ├── saveSystem.js
│ └── audio.js
│
└── /shaders
Step 1: Create package.json
{
"name": "open-world-game",
"version": "1.0.0",
"description": "Three.js Open World Game",
"scripts": {
"start": "vite"
},
"dependencies": {
"three": "^0.165.0"
},
"devDependencies": {
"vite": "^5.2.0"
}
}Step 2: Create index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Open World Game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="menu">
<h1>OPEN WORLD GAME</h1>
<button id="startBtn">Start Game</button>
</div>
<div id="hud">
<div id="health">Health: 100</div>
<div id="stamina">Stamina: 100</div>
<div id="coins">Coins: 0</div>
</div>
<canvas id="gameCanvas"></canvas>
<script type="module" src="./js/main.js"></script>
</body>
</html>Step 3: Create style.css
body {
margin: 0;
overflow: hidden;
font-family: Arial, sans-serif;
background: black;
}
canvas {
display: block;
}
#menu {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: white;
z-index: 10;
}
#menu button {
padding: 15px 30px;
font-size: 18px;
cursor: pointer;
border: none;
background: crimson;
color: white;
border-radius: 10px;
}
#hud {
position: absolute;
top: 20px;
left: 20px;
color: white;
z-index: 5;
}Step 4: Create js/main.js
import * as THREE from 'three';
import { createWorld } from './world.js';
import { createPlayer, movePlayer } from './player.js';
import { setupControls, keys } from './controls.js';
import { createEnemy, updateEnemy } from './enemy.js';
import { setupUI } from './ui.js';
import { createWeather } from './weather.js';
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x222222);
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const light = new THREE.DirectionalLight(0xffffff, 2);
light.position.set(10, 20, 10);
scene.add(light);
const ambient = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambient);
createWorld(scene);
createWeather(scene);
const player = createPlayer(scene);
const enemy = createEnemy(scene);
camera.position.set(0, 5, 10);
setupControls();
setupUI();
function animate() {
requestAnimationFrame(animate);
movePlayer(player, keys);
updateEnemy(enemy, player);
camera.position.x = player.position.x;
camera.position.z = player.position.z + 10;
camera.lookAt(player.position);
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});Step 5: Create js/world.js
import * as THREE from 'three';
export function createWorld(scene) {
const groundGeometry = new THREE.PlaneGeometry(500, 500);
const groundMaterial = new THREE.MeshStandardMaterial({
color: 0x1d5e2a
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
scene.add(ground);
for (let i = 0; i < 50; i++) {
const buildingGeometry = new THREE.BoxGeometry(
Math.random() * 5 + 2,
Math.random() * 20 + 5,
Math.random() * 5 + 2
);
const buildingMaterial = new THREE.MeshStandardMaterial({
color: 0x555555
});
const building = new THREE.Mesh(
buildingGeometry,
buildingMaterial
);
building.position.set(
(Math.random() - 0.5) * 200,
5,
(Math.random() - 0.5) * 200
);
scene.add(building);
}
}Step 6: Create js/player.js
import * as THREE from 'three';
export function createPlayer(scene) {
const geometry = new THREE.BoxGeometry(1, 2, 1);
const material = new THREE.MeshStandardMaterial({
color: 0x00ffcc
});
const player = new THREE.Mesh(geometry, material);
player.position.y = 1;
scene.add(player);
return player;
}
export function movePlayer(player, keys) {
const speed = 0.2;
if (keys['w']) player.position.z -= speed;
if (keys['s']) player.position.z += speed;
if (keys['a']) player.position.x -= speed;
if (keys['d']) player.position.x += speed;
}Step 7: Create js/controls.js
export const keys = {};
export function setupControls() {
window.addEventListener('keydown', (e) => {
keys[e.key.toLowerCase()] = true;
});
window.addEventListener('keyup', (e) => {
keys[e.key.toLowerCase()] = false;
});
}Step 8: Create js/enemy.js
import * as THREE from 'three';
export function createEnemy(scene) {
const geometry = new THREE.BoxGeometry(1, 2, 1);
const material = new THREE.MeshStandardMaterial({
color: 0xff0000
});
const enemy = new THREE.Mesh(geometry, material);
enemy.position.set(10, 1, 10);
scene.add(enemy);
return enemy;
}
export function updateEnemy(enemy, player) {
const direction = new THREE.Vector3();
direction.subVectors(player.position, enemy.position);
direction.normalize();
enemy.position.add(direction.multiplyScalar(0.03));
}Step 9: Create js/weather.js
import * as THREE from 'three';
export function createWeather(scene) {
const rainGeometry = new THREE.BufferGeometry();
const rainCount = 1000;
const positions = [];
for (let i = 0; i < rainCount; i++) {
positions.push(
Math.random() * 400 - 200,
Math.random() * 200,
Math.random() * 400 - 200
);
}
rainGeometry.setAttribute(
'position',
new THREE.Float32BufferAttribute(positions, 3)
);
const rainMaterial = new THREE.PointsMaterial({
color: 0xaaaaaa,
size: 0.2
});
const rain = new THREE.Points(rainGeometry, rainMaterial);
scene.add(rain);
}Step 10: Create js/ui.js
export function setupUI() {
const startBtn = document.getElementById('startBtn');
const menu = document.getElementById('menu');
startBtn.addEventListener('click', () => {
menu.style.display = 'none';
});
}Step 11: Create js/inventory.js
export const inventory = [];
export function addItem(item) {
inventory.push(item);
console.log('Added:', item);
}Step 12: Create js/missions.js
export const missions = [
{
id: 1,
title: 'Reach The City Center',
completed: false
},
{
id: 2,
title: 'Defeat Enemy',
completed: false
}
];Step 13: Create js/saveSystem.js
export function saveGame(data) {
localStorage.setItem('gameSave', JSON.stringify(data));
}
export function loadGame() {
return JSON.parse(localStorage.getItem('gameSave'));
}Step 14: Create js/audio.js
export function playMusic() {
const audio = new Audio('/assets/sounds/music.mp3');
audio.loop = true;
audio.volume = 0.5;
audio.play();
}Step 15: Create README.md
# Open World Game
## Installation
1. Install Node.js
2. Open terminal
3. Run:
npm install
4. Start game:
npm run start
5. Open browser URL shown in terminal
## Controls
WASD = Move
Mouse = Camera
ESC = Pause
## Features
- Open World
- Enemy AI
- Weather System
- Inventory
- Missions
- Save System
- UI HUDAdvanced Features To Add Next
Multiplayer
Use:
- Socket.io
- Node.js server
- Real-time synchronization
Realistic Characters
Use:
- Mixamo animations
- GLTFLoader
- FBX models
Vehicle Physics
Use:
- Cannon.js
- Ammo.js
Shooting System
Add:
- Raycasting
- Bullet particles
- Hit detection
AAA Graphics
Add:
- Bloom effects
- Shadows
- HDR environment
- SSAO
- Motion blur
NPC System
Add:
- Dialogue
- Shops
- AI paths
- Random movement
Future Improvements
- Zombie mode
- Online multiplayer
- Character customization
- Trading system
- Open world map
- Quest tracker
- Dynamic economy
- Police chase system
- Skill tree
- Voice chat
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What this error?
Traceback (most recent call last):
File "C:\Users\anjel\OneDrive\Área de Trabalho\progamas úteis\Pong.py", line 168, in
draw(window)
File "C:\Users\anjel\OneDrive\Área de Trabalho\progamas úteis\Pong.py", line 120, in draw
if int(ball_pos[0]) >= WIDTH + 1 - BALL_RADIUS - PAD_WIDTH and int(ball_pos[1]) in range(
TypeError: 'float' object cannot be interpreted as an integer