ArkaGame 2.6 – Adding keyboard commands

I think the mouse is better to control this game, but in case you want to use the keyboard, here is the code:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    movebar = "right"
                if event.key == pygame.K_LEFT:
                    movebar = "left"
                if event.key == pygame.K_UP:
                    movebar = "up"
                if event.key == pygame.K_DOWN:
                    movebar = "down"

and…

        # Keyboard commands
        if bar.x < 430:
            if movebar == "right":
                bar.x += 2
        if bar.x > 10:
            if movebar == "left":
                bar.x -= 2
        if bar.y > 400:
            if movebar == "up":
                bar.y -= 2
        if bar.y < 480:
            if movebar == "down":
                bar.y += 2

The whole code

# arkanoid
import pygame
from pygame import gfxdraw
import os
import sys
from random import choice, randrange
'''
arkapygame 2.6
================
4.7.2020
- fix the lives problem
- put a menu at the start
'''


class Brick:
    "One brick class"

    def __init__(self, x, y, randomcolor):
        self.x = x
        self.y = y
        self.color = randomcolor
        # This is for collisions
        self.rect = pygame.Rect(self.x, self.y, 50, 20)

    def update(self):
        # when you update it will go to self.x and self.y
        # bar.x is constantly equal to the mouse position in the while loop
        pygame.draw.rect(screen, self.color, (self.x, self.y, 50, 20))
        # pygame.draw.rect(screen, GREEN, (self.x, self.y, 50, 20))


class Bar:
    "This is the bar class"

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def update(self):
        
        pygame.draw.rect(screen, RED, (self.x, self.y, 60, 10))
        self.rect = pygame.Rect(self.x, self.y, 60, 10)


class Ball:
    "Draw Player 2"

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.color = RED

    def update(self):
        "The ball moves"
        global ball
        global ball_x, ball_y

        # sull'asse x Va verso sinistra
        if ball_x == "left":
            # sottraggo perchè vado a sinistra
            ball.x -= velx
            # se arriva a 10 rimbalza
            if ball.x < 10:
                pygame.mixer.Sound.play(s_wall)
                ball_x = "right"
        # va in basso
        if ball_y == 'down':
            # allora aumenta y quando va in basso (parte da 0 in alto)
            ball.y += vel_y
        if ball_y == 'up':
            # quando va in alto tolgo
            ball.y -= vel_y
            # se arriva in cima rimbalza in basso
            if ball.y < 30:
                pygame.mixer.Sound.play(s_wall)
                ball_y = 'down'
        # se va a destra aumenta x
        if ball_x == "right":
            ball.x += velx
            # a 480 rimbalza verso sinistra
            if ball.x > 490:
                pygame.mixer.Sound.play(s_wall)
                ball_x = "left"
        
        gfxdraw.filled_circle(screen, ball.x, ball.y, 6, self.color)
        # gfxdraw.filled_circle(screen, ball.x, ball.y, 5, YELLOW)
        self.rect = pygame.Rect(self.x, self.y, 6, 6)


def reverse():
    global ball_x, velx, vel_y
    ball_x = "right" if ball_x == "left" else "right"



def collision():
    global ball, bar, ball_y, ball_x, vely, velx, mousedir, bricks
    global diff, lives, stage, score, loop
    if ball.rect.colliderect(bar):
        pygame.mixer.Sound.play(hitbar)
        ball_y = "up"
        velx = 2 if diff > 0 else 1
        # print(f"you hit with diff: {diff} vel_x = {velx}")

    for n, brick in enumerate(bricks):
        if ball.rect.colliderect(brick):
            # screen.fill((0, 0, 0))
            pygame.draw.rect(screen, (0, 0, 0), (brick.x, brick.y, 50, 20))
            screen.blit(update_fps(color="Black"), (12, 10))
            score += 20
            screen.blit(update_fps(), (12, 10))
            pygame.mixer.Sound.play(hitbrick)
            # print("You hit a brick")
            if ball_y == "up":
                # the ball is lower than the brick of 20
                if ball.y == (brick.y + 20 - vel_y) :
                    ball_y = "down"
                # if the balls hit the brick on a side
                else:
                    if ball_x == "left":
                        ball_x = "right"
                    else:
                        ball_x = "left"
            elif ball_y == "down":
                if ball.y <= brick.y - 1:
                    ball_y = "up"
                else:
                    if ball_x == "left":
                        ball_x = "right"
                    else:
                        ball_x = "left"
            bricks.pop(n)
            if bricks == []:
                write_highest_score()
                screen.fill((0, 0, 0))
                ball.y = 300
                ball.x = 100
                if stage < len(blist):
                    stage += 1
                    pygame.mixer.Sound.play(s_ready)
                else:
                    stage = 0
                bricks = create_bricks(make_stages())
                show_bricks()

    # When the ball goes out of the screen in the bottom
    if ball.y > 510:
        ball.x, ball.y = 500, 300
        lives -= 1
        pygame.mixer.Sound.play(s_out)
        if lives < 0:
            pygame.mixer.Sound.play(s_over)
            score = 0
            stage = 0           
            ball_y = 'down'
            ball_x = 'left'
            # loop = 0
            velx = 1
            vely = 1


def pause():
    global stage

    pause = 1
    write("Arkanoid - Stage " + str(stage + 1), 200, 320)
    ball.update()
    bar.update()
    while pause:
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pause = 0
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_ESCAPE:
                    pause = 0
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    pause = 0
                if event.key == pygame.K_n:
                    generate_level()
        pygame.display.update()
        clock.tick(300)
    screen.fill((0, 0, 0))
    show_bricks()   

def generate_level():
    global bricks
    screen.fill((0, 0, 0))
    write("Arkanoid - Stage " + str(stage + 1), 200, 320)
    ball.update()
    bar.update()
    bricks = create_bricks(make_stages())
    show_bricks()


def restart():
    global score, lives, stage
    stage = 0 
    score = 0
    lives = 3
    generate_level()




def exit(event, loop):

    if event.type == pygame.QUIT:
        loop = 0
    if event.type == pygame.KEYUP:
        if event.key == pygame.K_ESCAPE:
            loop = 0
        if event.key == pygame.K_SPACE:
            pause()
    return loop


def create_bricks(blist):
    "The bricks scheme"
    bricks = []
    h = 30
    w = 0
    for line in blist:
        randomcolor = randrange(0,255), randrange(0,255), randrange(0,255),
        for brick in line:
            if brick == "1":
                bricks.append(Brick(50 + w * 51, h, randomcolor))
            w += 1
            if w == 8:
                w = 0
                h += 21
    return bricks


def show_bricks():
    for brick in bricks:
        brick.update()

stage = 0
lives = 3


def make_stages():
    blist = []
    for n in range(randrange(5,16)):
        riga = [str(choice([0, 1])) for x in range(4)]
        riga2 = riga[::-1]
        riga = riga + riga2
        # print(riga)
        blist.append("".join(riga))
    return blist


def write_highest_score():
    "Checks highest score when game's over"
    global score, scoremax

    with open("score.txt", "w") as file:
        if scoremax < score:
            file.write(str(score))


blist = make_stages()
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
ball_x = 'left'
ball_y = 'down'
# speed horizzontal
velx = 1
# speed vertical
vel_y = 1


######################
#     sound
#####################
pygame.mixer.pre_init(44100, -16, 1, 512)
pygame.init()
pygame.mixer.quit()
pygame.mixer.init(22050, -16, 2, 512)
pygame.mixer.set_num_channels(32)
# ===================================
hitbar = pygame.mixer.Sound('sound\\hitbar2.wav')
s_out = pygame.mixer.Sound('sound\\outspeech.wav')
hitbrick = pygame.mixer.Sound('sound\\hitbrick.wav')
s_ready = pygame.mixer.Sound('sound\\ready.wav')
s_over = pygame.mixer.Sound('sound\\over.wav')
s_wall = pygame.mixer.Sound('sound\\wall.wav')
# Soundtrack
# track1 = pygame.mixer.Sound('sound\\spectral_sound.wav')
 
clock = pygame.time.Clock()
screen = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Game")
startx = 0
bar = Bar(10, 480)
ball = Ball(100, 300)
bricks = create_bricks(blist)
background = pygame.image.load("img\\background.png").convert()
pygame.mouse.set_visible(False)
mousedir = "stop"
diff = 0
score = 0
font = pygame.font.SysFont("Arial", 14)
scoremax = 0

def update_fps(color="Coral"):
    global score, scoremax

    fps = f"Max: {scoremax} Lives: {lives} Stage: {stage} Score: {score} "
    fps_text = font.render(fps, 1, pygame.Color(color))
    return fps_text


def write(text, x, y, color="Coral",):
    text = font.render(text, 1, pygame.Color(color))
    text_rect = text.get_rect(center=(500//2, y))
    screen.blit(text, text_rect)
    return text


# pause()
show_bricks()
counter = 0
movebar = ""
def mainloop():
    # screen.blit(write("Pause"), (250, 250))
    global startx, mousedir, diff, counter, movebar
    pygame.mixer.Sound.play(s_ready)
    # pygame.mixer.Sound.play(track1)
    screen.fill((0, 0, 0))
    show_bricks()
    loop = 1
    while loop:
        # screen.blit(background, (0, 0))
        
        #screen.fill((0, 0, 0))
        pygame.draw.rect(screen, (0, 0, 0), (bar.x, bar.y, 60, 10))
        gfxdraw.filled_circle(screen, ball.x, ball.y, 6, (0, 0, 0))
        keys = pygame.key.get_pressed()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    movebar = "right"
                if event.key == pygame.K_LEFT:
                    movebar = "left"
                if event.key == pygame.K_UP:
                    movebar = "up"
                if event.key == pygame.K_DOWN:
                    movebar = "down"
                if event.key == pygame.K_ESCAPE:
                    loop = 0
                if event.key == pygame.K_SPACE:
                    pause()                
                if event.key == pygame.K_s:
                    pygame.image.save(screen, f"image{counter}.png")
                    counter += 1
                if event.key == pygame.K_r:
                    restart()
                if event.key == pygame.K_n:
                    generate_level()
            if event.type == pygame.KEYUP:
                movebar = ""
        
        # Keyboard commands
        if bar.x < 430:
            if movebar == "right":
                bar.x += 2
        if bar.x > 10:
            if movebar == "left":
                bar.x -= 2
        if bar.y > 400:
            if movebar == "up":
                bar.y -= 2
        if bar.y < 480:
            if movebar == "down":
                bar.y += 2
        #          Move with the mouse
        posx= pygame.mouse.get_pos()[0]
        
        if pygame.mouse.get_pos()[1] > 400:
            bar.y = pygame.mouse.get_pos()[1]
            pygame.mouse.set_pos(bar.x, bar.y)
        if posx > 10 and posx < 430:
            bar.x = posx


        
        # =======================================
        ball.update()
        bar.update()
        collision()
        if startx > posx:
            mousedir = "left"
        elif startx < posx:
            mousedir = "right"
        else:
            mousedir = "stop"
        diff = abs(startx - posx)
        startx = posx
        

        pygame.display.update()
        clock.tick(300)


# This should read the file with the highest score
try:
    if "score.txt" in os.listdir():
        with open("score.txt", "r") as file:
            # print("Scoremax = " + file.readlines()[0])
            scoremax = int(file.readlines()[0])
    else:
        with open("score.txt", "w") as file:
            file.write("100")
except:
    with open("score.txt", "w") as file:
        file.write("100")

def menu():
    loop = 1
    while loop:
        # screen.blit(background, (0, 0))
        write("Press space to start", 200, 320)
        write("Press r to restart during the game", 150, 340)
        #screen.fill((0, 0, 0))
        pygame.draw.rect(screen, (0, 0, 0), (bar.x, bar.y, 60, 10))
        gfxdraw.filled_circle(screen, ball.x, ball.y, 6, (0, 0, 0))
        keys = pygame.key.get_pressed()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_ESCAPE:
                    loop = 0

                if event.key == pygame.K_SPACE:
                    mainloop()
        pygame.display.update()
        clock.tick(300)

menu()

pygame.quit()

write_highest_score()

sys.exit()

 

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.