Skip to content

BakhatBug/8086-Assembly-Game

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

.model small .stack 100h .386

.data

is_over db 0

intro_msg db "Welcome to Brick Breaker Game!", 0Dh, 0Ah, 0DH, 0Ah
      	  db "Use 'A' and 'D' keys to move the paddle left and right.", 0Dh, 0Ah, 0DH, 0Ah
       	  db "Break all the bricks to win the game.", 0Dh, 0Ah, 0DH, 0Ah
      	  db "Press any key to start...$"
		  
exit_msg db 10,13,"GAME ENDED" , 10 , 13 , "You Scored : $"
score dw 0

window_width dw 140h								;the width of windows is  320p
window_height dw 0c8h								;height of the window is 200p
window_bounds dw 05h								;to check for the boundary to help proper bounce back of the ball

time_var db 0h										; contains the prev elapsed time

temp_brick_X dw 0
temp_brick_Y dw 0

bricks_X_1 dw 0fh, 4Bh, 87h, 0C3h, 0FFh
bricks_Y1 dw 0fh

bricks_X_2 dw 01Eh, 64h, 0AAh, 0F0h
bricks_Y2 dw 1Ah

bricks_X_3 dw 0fh, 4Bh, 87h, 0C3h, 0FFh 
bricks_Y3 dw 25h

bricks_X_4 dw 01Eh, 64h, 0AAh, 0F0h
bricks_Y4 dw 30h
bricks_height dw 05h
bricks_width  dw 32h

ball_original_X dw 80h								;original ball position at X when game starts
ball_original_Y dw 64h								;original ball position at Y when game starts
ball_X dw 80h										;current X position of the ball
ball_Y dw 64h										;current Y position of the ball
ball_velocity_X dw 02h								;speed of ball on X axis
ball_velocity_Y dw 02h								;speed of ball on Y axis
ball_size	dw 04h

paddle_Width    equ 40       ; Width of the paddle
paddle_Height   equ 5        ; Height of the paddle
paddle_Color    equ 0fh       ; Color of the paddle (white)
screenWidth     equ 320
screenHeight    equ 200
boundaryColor   equ 2        ; Green color
leftKey         equ    'a'   ; Left movement key
rightKey        equ    'd'      ; Right movement key								

paddle_X        dw 0AEh
paddle_Y        equ 190
keyPressed      db 97h

.code

main proc

mov ax , @data
mov ds , ax

call intro_page	
call clear_screen

check_time:
	
	mov ah , 2ch									;will contain CH = hours , Cl = miniutes , DH = seconds , dl = 1/100th second
	int 21h											;execute
	cmp dl , time_var								; compares current time with prev time to check if some time has passed
	je check_time
	
	mov time_var , dl								; updates the value of prev time to current time
	


    call Draw_Boundary_Top
    call Draw_Boundary_Bottom
    call Draw_Boundary_Left
    call Draw_Boundary_Right
    

	call move_ball			
	call move_Paddle
	
	call Load_Bricks

	call Draw_Ball
	call Draw_Paddle
	
	cmp is_over , 1
	je game_over
	
	cmp score , 180
	je game_over
	
	JMP check_time  								; after everything check time again 

game_over: call exit_page

mov ah , 4ch int 21h

main endp

; Procedure to draw a row of the paddle Draw_Row proc push cx ; Preserve cx push dx ; Preserve dx

Draw_Row_Loop: ; Draw a pixel at the current position mov ah, 0Ch ; BIOS function to set pixel mov al, paddle_Color ; Color of the paddle int 10h ; Call BIOS interrupt to draw the pixel

; Move to the next column
inc cx
dec bx                      ; Decrement the counter for remaining pixels in the row
jnz Draw_Row_Loop           ; Continue drawing if there are remaining pixels in the row

pop dx                      ; Restore dx
pop cx                      ; Restore cx
ret

Draw_Row endp

Draw_Boundary_Top proc mov cx, 0 ; Start column mov dx, 0 ; Start row

Draw_Boundary_Top_Loop: mov ah, 0Ch ; Write pixel mov al, boundaryColor int 10h inc cx ; Next column cmp cx, screenWidth jl Draw_Boundary_Top_Loop ; Loop until end of row ret Draw_Boundary_Top endp

Draw_Boundary_Bottom proc mov cx, 0 ; Start column mov dx, screenHeight - 1 ; Start row (bottom row)

Draw_Boundary_Bottom_Loop: mov ah, 0Ch ; Write pixel mov al, boundaryColor int 10h inc cx ; Next column cmp cx, screenWidth jl Draw_Boundary_Bottom_Loop ; Loop until end of row ret Draw_Boundary_Bottom endp

Draw_Boundary_Left proc mov cx, 0 ; Start column mov dx, 0 ; Start row

Draw_Boundary_Left_Loop: mov ah, 0Ch ; Write pixel mov al, boundaryColor int 10h inc dx ; Next row cmp dx, screenHeight jl Draw_Boundary_Left_Loop ; Loop until end of column ret Draw_Boundary_Left endp

Draw_Boundary_Right proc mov cx, screenWidth - 1 ; Start column (rightmost column) mov dx, 0 ; Start row

Draw_Boundary_Right_Loop: mov ah, 0Ch ; Write pixel mov al, boundaryColor int 10h inc dx ; Next row cmp dx, screenHeight jl Draw_Boundary_Right_Loop ; Loop until end of column ret Draw_Boundary_Right endp

Draw_Paddle proc mov cx, paddle_X ; Initial position of paddle's top-left corner (column) mov dx, paddle_Y ; Initial position of paddle's top-left corner (row)

Draw_Paddle_Loop: ; Draw a row of the paddle mov ax, paddle_X mov bx, paddle_Width ; Width of the paddle (number of pixels in a row) call Draw_Row

; Move to the next row
inc dx

; Check if all rows have been drawn
mov ax, dx
sub ax, paddle_Y            ; Compare the number of rows drawn with paddle height
cmp ax, paddle_Height
jle Draw_Paddle_Loop        ; Continue drawing if not all rows have been drawn

ret

Draw_Paddle endp

Erase_Paddle proc mov cx, paddle_X ; Initial position of paddle's top-left corner (column) mov dx, paddle_Y ; Initial position of paddle's top-left corner (row)

Erase_Paddle_Loop: ; Erase a row of the paddle mov ax, paddle_X mov bx, paddle_Width ; Width of the paddle (number of pixels in a row) call Erase_Row

; Move to the next row
inc dx

; Check if all rows have been erased
mov ax, dx
sub ax, paddle_Y                ; Compare the number of rows erased with paddle height
cmp ax, paddle_Height
jle Erase_Paddle_Loop           ; Continue erasing if not all rows have been erased

ret

Erase_Paddle endp

Erase_Row proc push cx ; Preserve cx push dx ; Preserve dx

Erase_Row_Loop: ; Erase a pixel at the current position (by setting it to the background color) mov ah, 0Ch ; BIOS function to set pixel mov al, 0h ; Background color int 10h ; Call BIOS interrupt to draw the pixel

; Move to the next column
inc cx
dec bx                          ; Decrement the counter for remaining pixels in the row
jnz Erase_Row_Loop             ; Continue erasing if there are remaining pixels in the row

pop dx                          ; Restore dx
pop cx                          ; Restore cx
ret

Erase_Row endp

Check_Keypress proc mov ah, 1 ; Check if a key has been pressed int 16h ret Check_Keypress endp

Move_Paddle proc ; Erase the previous position of the paddle call Erase_Paddle

mov ah, 1                   ; Check if a key has been pressed
int 16h
jz NoKeyPress               ; If no key has been pressed, skip movement

mov ah, 0                   ; Read the pressed key
int 16h
cmp al, leftKey             ; Compare with left movement key
je MoveLeft                 ; Move left if A key is pressed
cmp al, rightKey            ; Compare with right movement key
je MoveRight                ; Move right if D key is pressed

NoKeyPress: ret

MoveLeft: cmp paddle_X, 4 ; Check if the paddle is at the left boundary jle NoMovementLeft ; If yes, don't move left further sub paddle_X, 4 ; Move the paddle left ret

MoveRight: mov ax, paddle_X add ax, paddle_Width cmp ax, [screenWidth-4] ; Check if the paddle is at the right boundary jge NoMovementRight ; If yes, don't move right further add paddle_X, 4 ; Move the paddle right ret

NoMovementLeft: ; Optional: Play a sound or display a message for hitting the left boundary ret

NoMovementRight: ; Optional: Play a sound or display a message for hitting the right boundary ret

Move_Paddle endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; intro_page proc

    call clear_screen   	;Clear the screen

    mov ax, 04h			;Set up the video mode and text attributes
        int 10h 			;Set text mode


	    ;Display the introductory text
	    mov ah, 09h        ; Display string function
	    lea dx, intro_msg
	    int 21h

	   ;Wait for a key press
       mov ah, 00h
       int 16h

ret

intro_page endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

exit_page proc

    call clear_screen   	;Clear the screen

    mov ax, 04h			;Set up the video mode and text attributes
        int 10h 			;Set text mode


	    ;Display the introductory text
	    mov ah, 09h        ; Display string function
	    lea dx, exit_msg
	    int 21h
		
		mov ax , score
		call genericOutput
	   ;Wait for a key press
       mov ah, 00h
       int 16h

ret

exit_page endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; move_ball proc

call Erase_Ball
mov ax , ball_velocity_X
add ball_X , ax

mov ax , window_bounds
sub ax , ball_size
cmp ball_X , ax										;ball_X < 0 (yes -> ball collides with the left side)
jl rev_ball_X

mov ax , window_width
sub ax , window_bounds
sub ax , ball_size
cmp ball_X , ax										;ball_X > window_width (yes-> ball collides with the right side)
jg rev_ball_X

mov ax , ball_velocity_Y
add ball_Y , ax	

mov ax , window_bounds
sub ax , ball_size
cmp ball_Y , ax										;ball_Y < 0 (yes -> ball collides with the upper side)
jl rev_ball_Y

mov ax , window_height
sub ax , window_bounds
sub ax , ball_size
cmp ball_Y , ax										;ball_Y > window_height(yes-> ball collides with the bottom)
jg player_out

call Check_collision

ret

rev_ball_X:
	neg ball_velocity_X
	ret
	
rev_ball_Y:
	neg ball_velocity_Y
	ret
	
player_out:
	mov is_over , 1
	ret

move_ball endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Erase_Ball proc ; Draw over the ball's previous position with the background color mov cx , ball_X ; initial position of column mov dx , ball_Y ; initial position of row

Erase_Ball_Loop: mov ah , 0ch ; write to pixel mov al , 00h ; background color (black) int 10h ; execute with the configurations

inc cx              								; go to next column
mov ax , cx
sub ax , ball_X     								; compare number of pixels marked in columns
cmp ax , ball_size
JLE Erase_Ball_Loop

mov cx ,  ball_X    								; reset the column to initial
inc dx             									; move to the next row
mov ax , dx
sub ax , ball_Y     								; compare number of pixels marked in rows
cmp ax , ball_size
JLE Erase_Ball_Loop

ret

Erase_Ball endp

Reset_Ball_Position proc

mov ax , ball_original_X
mov ball_X , ax

mov ax , ball_original_Y
mov ball_Y , ax

ret

Reset_Ball_Position endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Draw_Ball proc

mov cx , ball_X										; intial position of column
mov dx , ball_Y										;initial position of column 

Draw_Ball_Loop: mov ah , 0ch ; write to pixel mov al , 0fh ;colour of ball is white int 10h ;execute with the configurations

	inc cx											; goes to next column
	mov ax , cx
	sub ax , ball_X									; compares number of pixels marked in columns
	cmp ax , ball_size
	JLE Draw_Ball_Loop
	
	mov cx ,  ball_X								; resets the coloumn to intial
	
	inc dx											; moves to the next row
	mov ax , dx			
	sub ax , ball_Y									; compares number of pixels marked in rows
	cmp ax , ball_size
	JLE Draw_Ball_Loop

ret

Draw_Ball endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; clear_screen proc

mov ah , 00h										;set's configuration mode to vedio
mov al , 04h										;select vedio mode
int 10h

mov ah , 0bh										;set configuration for background/pallete
mov bh , 00h										;select background
mov bl , 00h										;color it black
int 10h												;execute 


ret

clear_screen endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Draw_bricks proc

next_brick: mov cx , [si] ;move first element of brick_x in cx mov dx , [di] ;mov brick_y is dx

draw_brick_loop:

; works on same principle and drawing the paddle

mov ah, 0ch
mov al, 0fh
int 10h

inc cx
mov ax,cx
sub ax , [si]
cmp ax, bricks_width
jle draw_brick_loop

mov cx, [si]
inc dx
mov ax, dx
sub ax, [di]
cmp ax, bricks_height
jle draw_brick_loop

add si, 2											;increments by 2 since our array is dw
dec bx												;contains number of bricks to print in a row
jnz next_brick 

ret

Draw_bricks endp

Load_Bricks proc

	mov si, offset bricks_X_1 						;row1 coordinates	
	mov di, offset bricks_Y1 
	mov bx, 5                   					;no. of bricks
	call Draw_bricks

	mov si, offset bricks_X_2  						;row2 coordinates
	mov di, offset bricks_Y2
	mov bx, 4		   		 						;no. of bricks
	call Draw_bricks
	
	mov si, offset bricks_X_3  						;row3 coordinates	
	mov di, offset bricks_Y3 
	mov bx, 5                   					;no. of bricks
	call Draw_bricks

	mov si, offset bricks_X_4  						;row4 coordinates
	mov di, offset bricks_Y4
	mov bx, 4		   	 							;no. of bricks
	call Draw_bricks
ret

Load_Bricks endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Check_collision proc

;ball_X + ball_size > paddle_X && ball_X < paddle_X + paddle_width ; && ball_Y + ball_size > paddle_Y && ball_Y < paddle_Y + paddle_height

mov ax , ball_X										;condition 1
add ax , ball_size
cmp ax , paddle_X
jle ball_not_collide

mov ax , paddle_X									;condition 2
add ax , paddle_width
cmp ax , ball_X
jle ball_not_collide

mov ax , ball_Y										;condition 3
add ax , ball_size
cmp ax , paddle_Y
jle ball_not_collide

mov ax , paddle_Y									;condition 4
add ax , paddle_height
cmp ax , ball_Y
jle ball_not_collide

neg ball_velocity_Y

ball_not_collide:

	lea si , bricks_X_4								;load si with offset of row 4 bricks
	mov bx , bricks_Y4								; bx wil contain the row position
	mov cx , 4										; number of bricks
	call check_collision_brick
	
	lea si , bricks_X_3								;load si with offset of row 3 bricks	
	mov bx , bricks_Y3								; bx wil contain the row position
	mov cx , 5										; number of bricks
	call check_collision_brick
	
	lea si , bricks_X_2								;load si with offset of row 2 bricks
	mov bx , bricks_Y2								; bx wil contain the row position
	mov cx , 4										; number of bricks
	call check_collision_brick
	
	lea si , bricks_X_1								;load si with offset of row 1 bricks
	mov bx , bricks_Y1								; bx wil contain the row position
	mov cx , 5										; number of bricks
	call check_collision_brick
	
	ret

Check_collision endp

check_collision_brick proc

; If the ball doesn't collide with the Paddle we will compare it with the bricks

;ball_X + ball_size > Brick_X && ball_X < Brick_X + Brick_width ; && ball_Y + ball_size > Brick_Y && ball_Y < Brick_Y + Brick_height

mov temp_brick_Y , bx								; bx contains the Y position of bricks row

row: mov bx , [si]

cmp bx , -999										; put a sentinal value for the bricks which are already removed
je no_collision_brick

mov temp_brick_X , bx								;condition 1

mov ax , ball_X
add ax , ball_size
cmp ax , temp_brick_X
jle no_collision_brick

mov ax , temp_brick_X								;condition 2
add ax , bricks_width
cmp ax , ball_X
jle no_collision_brick

mov ax , ball_Y										;condition 3
add ax , ball_size
cmp ax , temp_brick_Y
jle no_collision_brick

mov ax , temp_brick_Y								;condition 4
add ax , bricks_height
cmp ax , ball_Y
jle no_collision_brick

mov bx , -999										; after confirming that the collision happens , we will put a sentinal value in it
mov [si] , bx

call clear_screen									; update the screen to remove the broken brick

add score , 10
neg ball_velocity_Y
jmp exit_check_collision

no_collision_brick: add si , 2 ; increment by 2 due to word type array dec cx jnz row

exit_check_collision:

ret check_collision_brick endp

genericOutput proc

mov cx,0
mov bx , 10

again:

xor dx,dx
div bx
push dx

inc cx
cmp ax,0
je print
jmp again

print: pop dx cmp dl,9 jbe digit add dl,7h digit: add dl,30h mov ah,2h int 21h dec cx jnz print

ret

genericOutput endp

end main

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published