MakeUseOf logo

How to Add Random Moving Objects Using Python's Arcade Library

Boy playing game on a pc with headphones and controller
No attribution required: Unsplash
Imran is a writer at MUO with 3 years of experience in writing technical content. He has also worked with many startups as a full-stack developer. He is passionate about writing and helping others learn about technology. In his free time, he enjoys exploring new programming languages.
Sign in to your MakeUseOf account

Random moving objects can bring excitement and unpredictability to games. It makes them more engaging and challenging for players. Python's Arcade library provides a simple and efficient way to incorporate random moving objects into your games.

Create a Simple Game

Before starting, make sure you have pip installed on your device. Use this command to install the arcade library:

pip install arcade

After that, create a window using the arcade.Window class and set the background color to white.

The code used in this article is available in this GitHub repository and is free for you to use under the MIT license.

Set the player's position to the middle of the screen horizontally and add a small distance from the top. You can control the player's movement using the arrow keys.

Here's the code for our basic game:

import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
PLAYER_RADIUS = 15
class MyGame(arcade.Window):
 def __init__(self, width, height):
 super().__init__(width, height)
 arcade.set_background_color(arcade.color.WHITE)
 self.player_x = SCREEN_WIDTH // 2
 self.player_y = PLAYER_RADIUS + 10
 def on_draw(self):
 arcade.start_render()
 arcade.draw_circle_filled(self.player_x, self.player_y, PLAYER_RADIUS, arcade.color.BLUE)
 def update(self, delta_time):
 pass
 def on_key_press(self, key, modifiers):
 if key == arcade.key.LEFT:
 self.player_x -= 5
 elif key == arcade.key.RIGHT:
 self.player_x += 5
if __name__ == "__main__":
 game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT)
 arcade.run()

Adding Multiple Objects

To add random moving objects to your game, create a list to store the object's positions and update them every frame. You can also use sprites as objects.

In your game code, add a list called objects to store the positions of the random moving objects. After that, generate the number of objects (NUM_OBJECTS) with random x and y coordinates within the screen boundaries. The objects are drawn as red circles using the arcade.draw_circle_filled function.

import arcade
import random
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
PLAYER_RADIUS = 15
OBJECT_RADIUS = 10
NUM_OBJECTS = 10
class MyGame(arcade.Window):
 def __init__(self, width, height):
 super().__init__(width, height)
 arcade.set_background_color(arcade.color.WHITE)
 self.player_x = SCREEN_WIDTH // 2
 self.player_y = PLAYER_RADIUS + 10
 self.objects = []
 for _ in range(NUM_OBJECTS):
 x = random.randint(0, SCREEN_WIDTH)
 y = random.randint(0, SCREEN_HEIGHT)
 self.objects.append((x, y))
 def on_draw(self):
 arcade.start_render()
 arcade.draw_circle_filled(self.player_x, self.player_y, PLAYER_RADIUS, arcade.color.BLUE)
 for obj in self.objects:
 x, y = obj
 arcade.draw_circle_filled(x, y, OBJECT_RADIUS, arcade.color.RED)
 def update(self, delta_time):
 pass
 def on_key_press(self, key, modifiers):
 if key == arcade.key.LEFT:
 self.player_x -= 5
 elif key == arcade.key.RIGHT:
 self.player_x += 5
if __name__ == "__main__":
 game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT)
 arcade.run()

Below is the output:

[画像:multiple objects placed randomly with player in arcade]
No attribution required: Screenshot by Imran

Implementing Random Movement Algorithm

To make the objects move randomly, update their positions in the update method using a random movement algorithm.

Iterate through each object and generate random values for dx and dy, representing the change in x and y coordinates. Then update the object's position by adding these values. Here's the modified code:

def update(self, delta_time):
 for i in range(NUM_OBJECTS):
 x, y = self.objects[i]
 dx = random.randint(-5, 5)
 dy = random.randint(-5, 5)
 x += dx
 y += dy
 self.objects[i] = (x, y)

Below is the output:

[画像:randomly moving objects with player in arcade]
No attribution required: Screenshot by Imran

Objects Moving Towards Player

To add more interaction, make the objects move toward the player. You can achieve this by calculating the direction vector between the object and the player and adjusting the object's position accordingly.

For this, calculate the differences in x and y coordinates between the object and the player. By normalizing these values, you obtain a direction vector. Then multiply this vector by a speed factor (3 in this case) and add it to the object's position. Here's the updated update method:

def update(self, delta_time):
 for i in range(NUM_OBJECTS):
 x, y = self.objects[i]
 dx = self.player_x - x
 dy = self.player_y - y
 distance = math.sqrt(dx ** 2 + dy ** 2)
 dx /= distance
 dy /= distance
 x += dx * 3
 y += dy * 3
 self.objects[i] = (x, y)

Below is the output:

[画像:objects moving towards player in arcade]
No attribution required: Screenshot by Imran

Objects Start to Move When the Player Enters Surrounding

To add further dynamics, modify the code so that the objects start moving only when the player enters their surrounding area. Add the code for the player's movement and define a radius within which the objects become active.

def update(self, delta_time):
 for i in range(NUM_OBJECTS):
 x, y = self.objects[i]
 dx = self.player_x - x
 dy = self.player_y - y
 distance = math.sqrt(dx ** 2 + dy ** 2)
 
 if distance < 100: # Adjust the radius as needed
 dx /= distance
 dy /= distance
 x += dx * 3
 y += dy * 3
 self.objects[i] = (x, y)

Collision Detection and Interaction

Now, add collision detection between the player and the objects, and define behavior when a collision occurs. Modify the update method to handle collisions:

def update(self, delta_time):
 for i in range(NUM_OBJECTS):
 x, y = self.objects[i]
 dx = self.player_x - x
 dy = self.player_y - y
 distance = math.sqrt(dx ** 2 + dy ** 2)
 
 if distance < PLAYER_RADIUS + OBJECT_RADIUS:
 # if collision occurred, handle it here
 self.objects.pop(i)
 self.objects.append((random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT)))
 
 elif distance < 100:
 dx /= distance
 dy /= distance
 x += dx * 3
 y += dy * 3
 self.objects[i] = (x, y)

Balancing Randomness

To create a balanced gameplay experience, it's important to fine-tune the random movement and spawning of objects. Here are a few examples of how you can adjust the code to achieve a better balance in your game:

Limiting Maximum Speed

To prevent objects from moving too fast, you can introduce a maximum speed limit. Modify the update method to include speed constraints:

def update(self, delta_time):
 for i in range(NUM_OBJECTS):
 x, y = self.objects[i]
 dx = self.player_x - x
 dy = self.player_y - y
 distance = math.sqrt(dx ** 2 + dy ** 2)
 if distance < PLAYER_RADIUS + OBJECT_RADIUS:
 self.objects.pop(i)
 self.objects.append((random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT)))
 elif distance < 100:
 dx /= distance
 dy /= distance
 speed = 3 # Adjust the speed value as needed
 dx = min(max(dx * speed, -MAX_SPEED), MAX_SPEED)
 dy = min(max(dy * speed, -MAX_SPEED), MAX_SPEED)
 x += dx
 y += dy
 self.objects[i] = (x, y)

Controlling Spawn Rate

You can also control the rate at which new objects spawn in the game. Adjust the code to include a delay between spawning new objects:

import time
class MyGame(arcade.Window):
 def __init__(self, width, height):
 super().__init__(width, height)
 arcade.set_background_color(arcade.color.WHITE)
 self.player_x = SCREEN_WIDTH // 2
 self.player_y = PLAYER_RADIUS + 10
 self.objects = []
 self.last_spawn_time = time.time()
 def update(self, delta_time):
 # control the spawning rate here
 if time.time() - self.last_spawn_time > SPAWN_DELAY:
 if len(self.objects) < MAX_OBJECTS:
 self.objects.append((random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT)))
 self.last_spawn_time = time.time()
 for i in range(len(self.objects)):
 x, y = self.objects[i]
 dx = self.player_x - x
 dy = self.player_y - y
 distance = math.sqrt(dx ** 2 + dy ** 2)
 if distance < PLAYER_RADIUS + OBJECT_RADIUS:
 self.objects.pop(i)
 self.objects.append((random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT)))
 elif distance < 100:
 dx /= distance
 dy /= distance
 x += dx * 3
 y += dy * 3
 self.objects[i] = (x, y)

Adjust the SPAWN_DELAY and MAX_OBJECTS values to find the right balance for your game. A longer delay or a smaller maximum number of objects will make the game less crowded. Whereas, a shorter delay or a larger maximum will increase the difficulty.

Make Games More Fun Using Moving Objects

Adding random moving objects to games can significantly enhance the overall experience. They introduce unpredictability and challenge, making the gameplay more engaging and dynamic. Players will have to adapt and react quickly to avoid collisions or catch objects, and that will provide a sense of excitement and accomplishment.

AltStyle によって変換されたページ (->オリジナル) /