0% found this document useful (0 votes)
36 views

CCASSCS028

This project report describes the development of two games - PING PONG and Mr.Toad. PING PONG is a two-player table tennis game where players can play against each other. Mr.Toad is a single-player game based on the T-Rex game. Both games use 2D graphics and focus only on gameplay, without artificial intelligence. The report includes details on the existing and proposed systems, feasibility study, software requirements, design documents, development process, and testing plans for the games.

Uploaded by

Irfan Shaikh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

CCASSCS028

This project report describes the development of two games - PING PONG and Mr.Toad. PING PONG is a two-player table tennis game where players can play against each other. Mr.Toad is a single-player game based on the T-Rex game. Both games use 2D graphics and focus only on gameplay, without artificial intelligence. The report includes details on the existing and proposed systems, feasibility study, software requirements, design documents, development process, and testing plans for the games.

Uploaded by

Irfan Shaikh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 63

GAME DEVELOPMENT

PROJECT REPORT

Submitted By
SNEHA K B
Reg. No. CCASSCS028
for the award of the Degree of
Bachelor of Science (B.Sc.)
in Computer Science
(University of Calicut)

under the guidance of


Ms. MINU MARY P J
Assistant Professor

BSc. COMPUTER SCIENCE


DEPARTMENT OF COMPUTER SCIENCE
CHRIST COLLEGE(Autonomous)
IRINJALAKUDA, KERALA
INDIA

March 2021
DEPARTMENT OF COMPUTER SCIENCE

CHRIST COLLEGE (AUTONOMOUS)

IRINJALAKUDA

CERTIFICATE

This is to certify that the project report entitled ”Game Development” is


a bonfied record of the project work done by Sneha K B in partial fulfill-
ment of the requirement for the sixth semester of Bachelor of Computer
Science in Department of Computer Science of CHRIST COLLEGE
(AUTONOMOUS) IRINJALAKUDA

Ms. Minu Mary P J Ms. Viji Viswanathan


Assistant Professor,CS Head of the Department
Internal Guide Computer Science

EXTERNAL EXAMINER INTERNAL EXAMINER


ACKNOWLEDGEMENT

First and foremost we like to thank Lord almighty for his providence
and for being the guiding light throughout the project. We wish to express
my sincere gratitude to our beloved Department head for giving me all the
facilities for our project. We take this opportunity to express my gratitude
to the class teacher Ms. SINI THOMAS and head of the department Ms.
VIJI VISWANATHAN who has been supported us throughout the course of
this project. We are thankful for her aspiring guidance and valuable advice
during the project work. We express my sincere thanks to my project guide
Ms. MINU MARY P J for supporting and guiding throughout the project.We
would take this opportunity to specially thank all other faculty members for
their constant and continuous motivation. Finally we would like to thank my
family and friends for giving valuable advice and moral support throughout
our project.
Declaration
We here by declare that this project work ”GAME DEVELOPMENT” sub-
mitted by Christ College (Autonomous)Irinjalakuda, affiliated to Calicut Uni-
versity in partial fulfillment of the requirement for the award of the Bachelor of
Computer Science, is a record of original work done by us,under the guidance of
Ms.MINU MARY P J, Department of Computer Science.

Place:Irinjalakuda
Date:

1
ABSTRACT

The proposed games PING PONG and Mr.Toad are digital game ver-
sion of the Table Tennis game and T-Rex game . Players will be able to
play the game in two-player mode in PING PONG and is single player in
Mr.Toad.The games PING PONG and Mr.Toad will not deal with in arti-
ficial intelligence and is solely be intended for two-players and single player
respectively. Due to the nature of the games, the graphics will be done in
2D and feel similar to that of the Table Tennis and T-Rex.
Contents
1 Introduction 1
1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 System Analysis 2
2.1 Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.1.1 Existing System . . . . . . . . . . . . . . . . . . . . . . . 2
2.1.2 Proposed System . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Problem definition . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.3 FEASIBILITY STUDY . . . . . . . . . . . . . . . . . . . . . . . 2
2.3.1 Technical Feasibility . . . . . . . . . . . . . . . . . . . . . 3
2.3.2 Economical Feasibility . . . . . . . . . . . . . . . . . . . . 3
2.3.3 Operational Feasibility . . . . . . . . . . . . . . . . . . . . 3

3 Software Requirement Specification 4


3.1 Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.3 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.3.1 Product Perspective . . . . . . . . . . . . . . . . . . . . . 4
3.3.2 Product Functionality . . . . . . . . . . . . . . . . . . . . 4
3.3.3 Users and CharacteristiTcs . . . . . . . . . . . . . . . . . 4
3.4 Specific Requirements . . . . . . . . . . . . . . . . . . . . . . . . 4
3.4.1 Hardware Requirements . . . . . . . . . . . . . . . . . . . 4
3.4.2 Software Requirements . . . . . . . . . . . . . . . . . . . . 5
3.5 Functional Requirements . . . . . . . . . . . . . . . . . . . . . . . 5
3.6 Non Functional Requirements . . . . . . . . . . . . . . . . . . . . 5
3.7 Interface Requirements . . . . . . . . . . . . . . . . . . . . . . . . 7
3.7.1 Hardware interfaces . . . . . . . . . . . . . . . . . . . . . 7
3.7.2 Software interfaces . . . . . . . . . . . . . . . . . . . . . . 7
3.7.3 Communication interfaces . . . . . . . . . . . . . . . . . . 7
3.8 Security Requirements . . . . . . . . . . . . . . . . . . . . . . . . 7
3.9 Platform Used . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.9.1 Windows 10 . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.9.2 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.9.3 Mac OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.10 Technologies Used . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4 Design Document 9
4.1 Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.2 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.3 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.4 Game Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.4.1 PING PONG . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.4.2 Mr.Toad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.5 Game Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4.5.1 AABB Collision . . . . . . . . . . . . . . . . . . . . . . . 10
4.6 Use Case Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . 12
4.6.1 PING PONG . . . . . . . . . . . . . . . . . . . . . . . . . 12
4.6.2 Mr.Toad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

5 Development of the System 13

6 System Testing 14
6.1 Test Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.1.1 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.1.2 Software risk issues . . . . . . . . . . . . . . . . . . . . . . 15
6.1.3 Features to be tested . . . . . . . . . . . . . . . . . . . . . 15
6.2 Test consolidation . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.2.1 Test item . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.2.2 Input specifications . . . . . . . . . . . . . . . . . . . . . . 16
6.2.3 PING PONG . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.2.4 Mr.Toad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

7 System Implementation and Maintenance 17


7.1 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
7.2 Maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
7.2.1 Corrective Maintenance . . . . . . . . . . . . . . . . . . . 17
7.2.2 Adaptive Maintenance . . . . . . . . . . . . . . . . . . . . 18
7.2.3 Enhanced Maintenance . . . . . . . . . . . . . . . . . . . 18
7.2.4 Preventive Maintenance . . . . . . . . . . . . . . . . . . . 18

8 Conclusion and Future Scope 19


8.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
8.2 Future Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Appendix 20

A USER INTERFACES 20
A.1 PING PONG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
A.2 Mr.Toad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

B CODE 25
B.1 PING PONG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
B.2 Mr.Toad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Christ College(Autonomous) Game Development

Chapter 1
1 Introduction
In this project, we design and implement two video games.
PING PONG is a computer game inspired from table tennis, which was a
popular and mind catching game in the early stages of digital game development.
Two users can play at the same time and it’s portable. This game can be run
on any computer having LOVE2D framework.
fhjdj The main features of Mr.Toad game are - It has a variety of states,
state change requires the keyboard input, mainly focused on detecting rectangle
collision. Mr.Toad is a game where the player controls a frog, attempting to
fly between columns of green pipes. The frog will be jumping until it collides
with a pipe or it falls on ground. It’s a simple game of infinite level type. It’s
a challenging game for all.
.

1.1 Overview
PING PONG
The main features of RETRO PING PONG game are - It has a variety of
states, state change requires the keyboard input, mainly focused on detecting
rectangle collision. It’s a multiplayer game.
Mr.Toad
In this game, the player can control the vertical movement of Mr.Toad (
every pressing on the keyboard makes Mr.Toad leap upward for a little bit, and
he will fall freely without control).
Both are written in lua language and executed using LOVE2D framework.

Department of Computer Science 1


Christ College(Autonomous) Game Development

Chapter 2
2 System Analysis
2.1 Purpose
The primary goal of this project was to increase understanding of the video
game industry’s creation methods, communication behaviors, and attitudes for
the purpose of building more accurate models of preservation and collection
development.

2.1.1 Existing System


PING PONG Table tennis, also known as ping-pong is a sport in which two
players hit a lightweight ball, also known as the ping-pong ball, back and forth
across a table using small rackets. The game takes place on a hard table divided
by a net.
Mr.Toad T-Rex Game or Dino Runner and initially code named Project Bolan,
is a built-in browser game in the Google.

2.1.2 Proposed System


PING PONG We adapted Table Tennis game into digital platform with sound
effects, score boards, player serves. Instead of rackets, rectangle shaped paddles
are used and ball is replaced with square. Attractive background color makes
the players more interested to focus with a maximum of 10 scores to become
the winner.
Mr.Toad Taking T-Rex Game as a base we implemented Mr.Toad with more
attractive user interface, with sound effects, score boards, images to loop on the
background.

2.2 Problem definition


This project is developed for indoor entertainment purposes due to COVID-19
panademic.

2.3 FEASIBILITY STUDY


After the problem is clearly understood and solutions proposed, the next step
is to conduct the feasibility study. Feasibility study is defined as evaluation
or analysis of the potential impact of the proposed project or program. The
objective is to determine whether the proposed system is feasible. There are
three aspects of feasibility study to which the proposed system is subjected as
discussed below.

Department of Computer Science 2


Christ College(Autonomous) Game Development

2.3.1 Technical Feasibility


Technical feasibility assess whether the current technical resources are sufficient
for the new system. We can upgrade the level of technology for supporting our
website. We check whether the proposed system can be implemented in the
present system without supporting the existing hardware.

2.3.2 Economical Feasibility


Economic feasibility determines whether the time and money are available to
develop the system. There is no additional hardware used to develop the site,
it is inexpensive to build.

2.3.3 Operational Feasibility


Operational feasibility determines if the human resources are available to oper-
ate the system once it has been installed. No extra training is needed to use
this system. Anyone who has knowledge in internet in english language can
easily use the system. The resources that are required to implement or install
are already available with the organization.

Department of Computer Science 3


Christ College(Autonomous) Game Development

Chapter 3
3 Software Requirement Specification
3.1 Purpose
The purpose of this document is to give a detailed description of the require-
ments for the Game Development. It illustrate the purpose and complete de-
scription for the development of the system. It explain system constraints,
interface. This document is primarily intended to be proposed for digital games
and a reference for the upcoming students of the college.

3.2 Scope
Our project has made it easier for everyone to create their own digital games.
Playing video games fulfills a purpose in their lives. This could include gaming
for: relaxation, opportunities to exert control, enjoyment, creativity, socializa-
tion, prevent boredom, challenge, and achievement. It could also be used as a
coping method or stress management.

3.3 Overview
The purpose of this document is to help the reader to visualise the solution to
the project presented.

3.3.1 Product Perspective


Our project is mainly focused on entertainment purposes.This project can be
implemented in any computer that supports LOVE2D framework.

3.3.2 Product Functionality


In PING PONG two players can play at a time, where each player can handle
one of the two paddles at a time. Mr.Toad is a single player game where the
player can handle Mr.Toad using space bar.

3.3.3 Users and CharacteristiTcs


In PING PONG there are two players each can control one of the two paddles
to direct the ball to the oponent’s side. In Mr.Toad the player control Toad by
space bar to move persistently to the right through the pairs of pipes.

3.4 Specific Requirements


3.4.1 Hardware Requirements
ˆ System: IBM-Compatible PC

Department of Computer Science 4


Christ College(Autonomous) Game Development

ˆ Processor: Intel® Pentium® IV 2.4 GHz or AMD 3500+


ˆ Speed: Above 1GHz
ˆ RAM capacity:2 GB
ˆ Graphics: OpenGL 2.1 or OpenGL ES 2
ˆ Keyboard: Standard
ˆ Mouse: Standard
ˆ Monitor: SVGA Color

3.4.2 Software Requirements


ˆ Operating System: Windows XP/Linux/Mac OS
ˆ Languages used: Lua
ˆ Framework used: LOVE2D

3.5 Functional Requirements


It contains three main modules.
ˆ 1.Two players in PING PONG
ˆ 2.Single player in Mr.Toad

Two players in PING PONG


Each player will control the paddle in their respective side to hit the ball to
prevent it from going out of boundary. Each player can interact with the ball
only when the ball reaches near their paddle.

Single player in Mr.Toad


The player will control the movement of Mr.Toad using space bar inorder to
help Mr.Toad to go through the pair of pipes without colliding.

3.6 Non Functional Requirements


Non-functional requirements define the overall qualities or attributes of the re-
sulting system. Non-functional system place restrictions on the product be-
ing developed, the developed process, and specify external constraints that the
product must meet. Examples of non-functional requirements include safety,
security, usability, reliability and performance requirements. Project manage-
ment issues (costs, time and schedule) are often considered as non-functional
requirements. The principal non - functional constraints which are relevant to
critical systems :

Department of Computer Science 5


Christ College(Autonomous) Game Development

ˆ performance

ˆ security

ˆ safety

ˆ usability

Performance
Performance requirements concern the speed of operation of a system. Types
of performance requirements :
ˆ Response requirements (how quickly the system reacts to a user input).

ˆ Throughput requirements (how much the system can accomplish within a


specified amount of time).
ˆ Availability requirements (is the system available for service when re-
quested by end users). The speed of operation of this system is adequate
for the requirements.

Reliability
ˆ Reliability is the ability of a system to perform its required function under
stated conditions for a specified period of time.
ˆ constraints on the runtime behavior of the system. This system is reliable
because its functionalities can be done on the required conditions.
Safety
Safety requirements are not required which exclude unsafe situation from
the possible solution of the system.

Department of Computer Science 6


Christ College(Autonomous) Game Development

Usability
Usability is the ease with which a user can learn to operate, prepare inputs
for, and interpret outputs of system or components. Usability requirements
include :
ˆ well-formed user interfaces.

3.7 Interface Requirements


3.7.1 Hardware interfaces
The system must have LOVE2D framework.

3.7.2 Software interfaces


Software interface required for the working of the project is the appropriate
operating system.

3.7.3 Communication interfaces


The user of the game communicate using keyboard.

3.8 Security Requirements


ˆ User accesses only their account.

ˆ Validation of input is handled.

ˆ This application containing the computer systems is physically secured


against arms or surreptitious entry by intruders.
ˆ Users must be authorized carefully to reduce changes of any such user
giving access to an intruder in exchange for a bribe or other favour.

3.9 Platform Used


3.9.1 Windows 10
Windows 10 is a major version of the Microsoft Windows operating system
that was released on July 29, 2015.It is built on the Windows NT kernel and
follows windows 8.Part of the reason Microsoft decided to name the 2015 release
”Windows 10”(and skipped ”windows 9”)is because the operating system is
designed to be a new direction for Microsoft. One of the primary aims of
windows 10 is to Unify the windows experience across multiple devices, such
desktop computers, tablets, and smartphones. As part of this effort, Microsoft
developed Windows10 Mobile alongside Windows 10 to replaces Windows Phone
- Microsoft’s previous mobile OS. Windows 10 also integrates other Microsoft
services, such as Xbox Live and the Cortana voice recognition assistant.

Department of Computer Science 7


Christ College(Autonomous) Game Development

3.9.2 Linux
Linux is an operating system. Linux has been around since the mid-1990s and
has since reached a user-base that spans the globe. In fact, one of the most popu-
lar platforms on the planet, Android, is powered by the Linux operating system.
An operating system is software that manages all of the hardware resources as-
sociated with your desktop or laptop. To put it simply, the operating system
manages the communication between your software and your hardware.Linux is
also distributed under an open source license. Linux has a number of different
versions to suit any type of user.

3.9.3 Mac OS
Mac OS, operating system (OS) developed by the American computer company
Apple Inc. The OS was introduced in 1984 to run the company’s Macintosh
line of personal computers (PCs). The Macintosh heralded the era of graphical
user interface (GUI) systems, and it inspired Microsoft Corporation to develop
its own GUI, the Windows OS. In the 1980s Apple made an agreement allowing
Microsoft to use certain aspects of the Mac interface in early versions of Win-
dows. However, except for a brief period in the 1990s, Mac OS has never been
licensed for use with computers made by manufacturers other than Apple.

3.10 Technologies Used


Lua
”Lua” (pronounced LOO-ah) means ”Moon” in Portuguese. Lua is a pow-
erful, efficient, lightweight, embeddable scripting language. It supports pro-
cedural programming, object-oriented programming, functional programming,
data-driven programming, and data description.
Lua combines simple procedural syntax with powerful data description con-
structs based on associative arrays and extensible semantics. Lua is dynamically
typed, runs by interpreting bytecode with a register-based virtual machine, and
has automatic memory management with incremental garbage collection, mak-
ing it ideal for configuration, scripting, and rapid prototyping.

Department of Computer Science 8


Christ College(Autonomous) Game Development

Chapter 4
4 Design Document
4.1 Purpose
Game Development is the art of creating games and describes the design, devel-
opment and release of a game. It may involve concept generation, design, build,
test and release.The benefit of this project is very high because you can make
your own games, you don’t need a degree to make games, you get to be cre-
ative. Both games demonstrated in our project are 2-dimensional developed on
the basis of AABB collision theory. PING PONG is made of rectangular blocks.
Player moves the paddle to hit the ball back to the oponent’s side. Mr.Toad
is made of moving pictures where the player moves Mr.Toad to the right using
space bar and pass each pair of pipe to gain points. Purpose of this document
is to give the detailed description of the architecture and design for the games.

4.2 Scope
Game Development is a project aimed at developing the games using lua lan-
guage. It makes easier for everyone to understand the steps in developing games
and it’s ideas.

4.3 Overview
The purpose of this document is to help the reader to visualize the solution to
the project presented.

4.4 Game Design


4.4.1 PING PONG
Player1 can handle the paddle on left. W key will move the paddle upward and
S key Will move it downward. Player1 can handle the paddle on left. Up key
will move the paddle upward and Down key Will move it downward. Collision
is checked on every 1/60 th second. AABB collision theory is used to check the
collision between ball and paddle. If the collision is detected, the ball will move
in the opposite direction towards the other player. The game will continue until
one of the player scores 10. After that the game will restart.

4.4.2 Mr.Toad
Mr.Toad is a frog (who is very much eager to find his princess in the castle)
. So he need to move between the pairs of pipes without colliding in order to
reach final destination. It’s an infinite loop of pipes. If he touches the pipe, it
will lead to his failure and has to start from the beginning.

Department of Computer Science 9


Christ College(Autonomous) Game Development

4.5 Game Logic


Both game follows one of the most popular collision theory called AABB collision
theory: AABB COLLISION

4.5.1 AABB Collision


AABB stands for axis-aligned bounding box, a rectangular collision shape aligned
to the base axes of the scene, which in 2D aligns to the x and y axis. Being
axis-aligned means the rectangular box has no rotation and its edges are parallel
to the base axes of the scene (e.g. left and right edge are parallel to the y axis).
The fact that these boxes are always aligned to the axes of the scene makes
calculations easier. Here we surround the ball object with an AABB:

Almost all the objects in Breakout are rectangular based objects, so it makes
perfect sense to use axis aligned bounding boxes for detecting collisions. This
is exactly what we’re going to do.
Axis aligned bounding boxes can be defined in several ways. One of them is
to define an AABB by a top-left and a bottom-right position. The GameObject
class that we defined already contains a top-left position (its Position vector),
and we can easily calculate its bottom-right position by adding its size to the
top-left position vector (Position + Size). Effectively, each GameObject contains

Department of Computer Science 10


Christ College(Autonomous) Game Development

an AABB that we can use for collisions.


So how do we check for collisions? A collision occurs when two collision
shapes enter each other’s regions e.g. the shape that determines the first object
is in some way inside the shape of the second object. For AABBs this is quite
easy to determine due to the fact that they’re aligned to the scene’s axes: we
check for each axis if the two object’ edges on that axis overlap. So we check if
the horizontal edges overlap, and if the vertical edges overlap of both objects.
If both the horizontal and vertical edges overlap we have a collision.

Department of Computer Science 11


Christ College(Autonomous) Game Development

4.6 Use Case Diagram


4.6.1 PING PONG

Department of Computer Science 12


Christ College(Autonomous) Game Development

4.6.2 Mr.Toad

Department of Computer Science 13


Christ College(Autonomous) Game Development

Chapter 5
5 Development of the System
PING PONG and Mr.Toad is composed of different classes. In PING PONG
each objects in the game like paddle, ball have their own class. Same goes for
Mr.Toad. These classes are later imported to main program file using import
function. Every action even the importing of class is done with the help of
codes. There are a lot of codes available for such purposes in the online forums
which makes it easier for developers to use it without other formalities.

Department of Computer Science 14


Christ College(Autonomous) Game Development

Chapter 6
6 System Testing
Testing is the penultimate step of any game development.With the constant
growth and expansion of the gaming industry worldwide, top leaders in this
industry like AltSpaceVR and BigScreenVR, are accelerating a virtual future
probably faster than many wait for. However, it is vital for the gaming com-
panies to not only focus on future trends but also to identify the user’s needs.
Delivering an end gaming product with errors and bugs will bring about crit-
icism from the end-users, which in turn can lead to a huge reduction in unit
sales.

6.1 Test Plan


6.1.1 Scope
This test plan will cover the following testing activities as identified in the testing
strategy.

ˆ Functionality Testing

This type of testing is done to confirm whether the end product works following
the specifications. Functionality QA testers mainly hunt for the generic prob-
lems within the game or its graphics and user interface, such as game asset
integrity, stability issues, audio-visual issues, and game mechanic issues. Few
things that proficient game testers consider while testing the interactive ap-
plications comprise performance issues like freezing, crashing, and progression
blockages. User interface (UI) tests, on the flip side, make sure user-friendliness
of the game. UI testing crucially aims at highlighting two significant things,
both the content types and the graphical elements. Besides, localization tests
of the game should also be covered.

ˆ Combinatorial Testing

By making use of this method, you can effortlessly test the game rapidly in its
earliest stages. Initially, the initial step is to discover how much testing your
game necessitates. For this reason, you can use this particular type of testing to
determine whether the game satisfies the definite requirements or functions bug-
free. Besides, it also analyzes and scrutinizes all the outputs and inputs of the
game so you can get a clear image concerning distinct conceivable combinations
and outcomes. It is mostly used for commercial software testing to generate test
cases. The execution of combinatorial testing techniques in video game testing
improves the effectiveness of test execution, quality, phase containment, and
cost.
ˆ Ad Hoc Testing

Department of Computer Science 15


Christ College(Autonomous) Game Development

Ad hoc testing often referred as ‘’general testing” is a less structured way of


testing and it is randomly done on any section of the gaming application. Specif-
ically, there are two distinct types of ad hoc testing. This kind of testing works
on the technique called “error guessing” and requires no documentation or pro-
cess or planning to be followed. Since Ad hoc testing aims at detecting defects
or errors through a random approach, with zero documentation, errors won’t
be mapped to test cases. There are three different types of Adhoc testing; Pair
testing, Buddy testing, and Monkey testing. The benefit of this type of testing
is to ensure the completeness of testing and detect hidden errors or bugs than
planned testing.

ˆ Compatibility Testing

Compatibility testing aims to detect any defects in the functionality and shows
if the final product meets the essential requirements of the software, hardware,
and graphics. It’s better to keep the game users happy after all. Conducting
this type of test helps to validate whether the games UI (user interface) is
optimized for varied screen sizes of different handsets. This is done for both
mobile and PC games. For instance, in mobile games, this would be used for
testing whether the game will functions properly on the various sets of Android
devices. This technique can evaluate the compatibility of your game on different
gaming platforms.

ˆ Regression testing

It is used to scrutinize the functionality of the complete features of the gaming


application. Here test cases are re-checked to analyze the working of the previous
functions of the app works fine and that new changes have not introduced any
new errors or vulnerabilities. The aim is to recheck whether the functions of the
app works fine, or verify whether any changes have popped up any new bugs
or caused any break. This is important to maintain the end product’s quality
control and spot bugs at the primary stages of product development. With this
type of significant game testing technique, a developer could re-run the earlier
conducted tests and compare the old vs. current results to observe if there are
any errors.

6.1.2 Software risk issues


In this section, the plan is to test the risk involved in critical issues.

6.1.3 Features to be tested


ˆ Test whether there is any problem in the code.

ˆ Test whether the game logic works properly.

ˆ Test whether the AABB collision theorem works properly.

Department of Computer Science 16


Christ College(Autonomous) Game Development

ˆ Test whether all games are loaded correctly.

ˆ Test whether score and other instructions are displayed correctly.

ˆ Test whether the provided security works correctly.

6.2 Test consolidation


6.2.1 Test item
The items or features to be tested in the test cases are included in the document.
Each and every user input is tested. The present condition of the system is
tested. It is checked to make sure that environment is ready for the application
to work.

6.2.2 Input specifications


These are the inputs required to execute the test case. All required inputs in-
cluding data elements and values are given below.

6.2.3 PING PONG


Key Operation
Up To move the Paddle up for Player1
Down To move the Paddle down for Player1
W To move the Paddle up for Player2
S To move the Paddle down for Player2
enter To change the state of game

6.2.4 Mr.Toad
Key Operation
Space bar To move in right direction
enter To change the state of game

Department of Computer Science 17


Christ College(Autonomous) Game Development

Chapter 7
7 System Implementation and Maintenance
7.1 Implementation
System implementation is the conversion of new system into an operating one
which involves creating compatible files, training clients and installing hardware.
User training is crucial for minimizing resistance to change and giving chance
to prove its worth. Training aids user friendly manuals and healthy screens
provide the user with a good start. Software maintenance follows conversion
to the extent that changes are necessary to maintain satisfactory operations
relative to changes in the user’s environment. Maintenance often includes minor
enhancements or corrections to the problem that surface late in the systems
operations. In the implementation phase, the team builds the components either
from scratch or by composition. Given the architecture document meant from
the design phase and the requirement document from the analysis phase, the
team should build exactly what has been requested, though there is still room for
innovation and flexibility. For example, a component may be narrowly designed
for this particular system, or the component may be made more general to
satisfy a reusability
ˆ Careful planning
ˆ Investigation of system and constraints
ˆ Design the methods to achieve changeover.
ˆ Training the staff in the changed phase.
ˆ Evaluation of change over method.
ˆ The method of implementation and time scale to be adopted are found
out initially.

7.2 Maintenance
This phase occurs as a result of deploying the whole system at the end users
organization. They will perform the beta testing at the end users and inform to
the developers about any needed modification to the application. The customer
records all the problems that are encountered during the beta testing and reports
these to the developer at regular intervals.

7.2.1 Corrective Maintenance


Even with the best quality assurance activities, it is likely that the customer will
uncover defects in the software. Corrective maintenance changes the software
to correct the defects. Corrective Maintenance activity may consist of repair,

Department of Computer Science 18


Christ College(Autonomous) Game Development

restoration or replacement of equipment. This activity will be result of a regular


inspection, which identifies the failure in time for corrective maintenance to be
planned and scheduled, then performed during a routine maintenance shutdown.

7.2.2 Adaptive Maintenance


Over time, the original environment(CPU, operating system, business rules,
external product characteristics) for which the software was developed is likely
to change. Adaptive maintenance results in modification to the software to
accommodate changes to its external environment.

7.2.3 Enhanced Maintenance


As software is used, the customer/user will recognize additional functions that
will provide the benefit. Perfect maintenance extends the software beyond its
original functional requirements.

7.2.4 Preventive Maintenance


Computer software deteriorates due to change, and because of this preventive
maintenance often called software re-engineering, must be conducted to en-
able the software to serve the needs of its end users. Preventive maintenance
makes changes to computer programs so that they can be more easily corrected,
adapted and enhanced.

Department of Computer Science 19


Christ College(Autonomous) Game Development

Chapter 8
8 Conclusion and Future Scope
8.1 Conclusion
PING PONG: There are two players that can play the game at a time. Each
player can handle one of the paddles using the control keys (up and down keys
, w and s keys).
Mr.Toad : Single player will control the jumping of Mr.Toad using the space
bar and try to pass between the pipes.

8.2 Future Scope


ˆ Mobile Application

ˆ Data Base

ˆ Online players

Department of Computer Science 20


Christ College(Autonomous) Game Development

Appendix
A USER INTERFACES
A.1 PING PONG

Department of Computer Science 21


Christ College(Autonomous) Game Development

Department of Computer Science 22


Christ College(Autonomous) Game Development

Department of Computer Science 23


Christ College(Autonomous) Game Development

A.2 Mr.Toad

Department of Computer Science 24


Christ College(Autonomous) Game Development

Department of Computer Science 25


Christ College(Autonomous) Game Development

B CODE
B.1 PING PONG
main.lua
[breaklines=true]
push = require ’push’
Class = require ’class’
require ’Paddle’
require ’Ball’

WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720

VIRTUAL_WIDTH = 432
VIRTUAL_HEIGHT = 243

-- speed at which we will move our paddle; multiplied by dt in update


PADDLE_SPEED = 200

function love.load()

love.graphics.setDefaultFilter(’nearest’, ’nearest’)
love.window.setTitle(’Pong’)
math.randomseed(os.time())
smallFont = love.graphics.newFont(’retro.ttf’, 8)
fpsFont = love.graphics.newFont(’retro.ttf’, 8)
largeFont = love.graphics.newFont(’retro.ttf’, 16)
scoreFont = love.graphics.newFont(’font.ttf’, 32)

love.graphics.setFont(smallFont)
sounds = {
[’paddle_hit’] = love.audio.newSource(’sounds/ping.mp3’, ’static’ ),
[’score’] = love.audio.newSource(’sounds/score.wav’, ’static’),
[’wall_hit’] = love.audio.newSource(’sounds/bounce.mp3’, ’static’)
}-- called either by sounds.score or sounds[’score’] to execute sounds.score:play()
push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, {
fullscreen = true,
resizable = false,
vsync = true
})
player1Score = 0
player2Score = 0

servingPlayer = 1

Department of Computer Science 26


Christ College(Autonomous) Game Development

player1 = Paddle(10, 30, 5, 30)


player2 = Paddle(VIRTUAL_WIDTH - 10, VIRTUAL_HEIGHT - 30, 5, 30)
ball = Ball(VIRTUAL_WIDTH / 2 - 2, VIRTUAL_HEIGHT / 2 - 2, 4, 4)

gameState = ’start’
love.graphics.setBackgroundColor(0, 1, 0)
end

function love.resize(w, h)
push:resize(w,h)
end

function love.update(dt)
if gameState == ’serve’ then
love.graphics.setBackgroundColor(0, 1, 0)
-- before switching to play, initialize ball’s velocity based
-- on player who last scored
ball.dy = math.random(-50, 50)
if servingPlayer == 1 then
ball.dx = math.random(140, 200)
else
ball.dx = -math.random(140, 200)
end
elseif gameState == ’play’ then
love.graphics.setBackgroundColor(0, 1, 0)
-- detect ball collision with paddles, reversing dx if true and
-- slightly increasing it, then altering the dy based on the position of collision
if ball:collides(player1) then
sounds.paddle_hit:play()
ball.dx = -ball.dx * 1.03
ball.x = player1.x + 5

-- keep velocity going in the same direction, but randomize it


if ball.dy < 0 then
ball.dy = -math.random(10, 150)
else
ball.dy = math.random(10, 150)
end
end
if ball:collides(player2) then
sounds.paddle_hit:play()
ball.dx = -ball.dx * 1.03
ball.x = player2.x - 4

-- keep velocity going in the same direction, but randomize it


if ball.dy < 0 then

Department of Computer Science 27


Christ College(Autonomous) Game Development

ball.dy = -math.random(10, 150)


else
ball.dy = math.random(10, 150)
end
end

-- detect upper and lower screen boundary collision and reverse if collided
if ball.y <= 0 then
sounds.wall_hit:play()
ball.y = 0
ball.dy = -ball.dy
end

-- -4 to account for the ball’s size


if ball.y >= VIRTUAL_HEIGHT - 4 then
sounds.wall_hit:play()
ball.y = VIRTUAL_HEIGHT - 4
ball.dy = -ball.dy
end
if ball.x < 0 then
sounds.score:play()
servingPlayer = 1
player2Score = player2Score + 1

if player2Score == 10 then
winningPlayer = 2
gameState = ’done’

else
gameState = ’serve’
ball:reset()
end
end
if ball.x > VIRTUAL_WIDTH then
sounds.score:play()
servingPlayer = 2
player1Score = player1Score + 1

if player1Score == 10 then
winningPlayer = 1
gameState = ’done’
else
gameState = ’serve’
ball:reset()
end
end

Department of Computer Science 28


Christ College(Autonomous) Game Development

end

-- if we reach the left or right edge of the screen,


-- go back to start and update the score

-- player 1 movement
if love.keyboard.isDown(’w’) then
player1.dy = -PADDLE_SPEED
elseif love.keyboard.isDown(’s’) then
player1.dy = PADDLE_SPEED
else
player1.dy = 0
end

-- player 2 movement
if love.keyboard.isDown(’up’) then
player2.dy = -PADDLE_SPEED
elseif love.keyboard.isDown(’down’) then
player2.dy = PADDLE_SPEED
else
player2.dy = 0
end

-- update our ball based on its DX and DY only if we’re in play state;
-- scale the velocity by dt so movement is framerate-independent
if gameState == ’play’ then
ball:update(dt)
end

player1:update(dt)
player2:update(dt)
end

function love.keypressed(key)

if key == ’escape’ then


love.event.quit()
-- if we press enter during either the start or serve phase, it should
-- transition to the next appropriate state
elseif key == ’enter’ or key == ’return’ then
love.graphics.setBackgroundColor(0, 1, 0)
if gameState == ’start’ then
gameState = ’serve’

Department of Computer Science 29


Christ College(Autonomous) Game Development

elseif gameState == ’serve’ then


gameState = ’play’
elseif gameState == ’done’ then
gameState = ’serve’
-- may be we can increase the level ball:reset
-- by changing here

player1Score = 0
player2Score = 0

if winningPlayer == 1 then
servingPlayer = 2
else
servingPlayer = 1
end
end
end
end

function love.draw()

push:apply(’start’)

love.graphics.setFont(smallFont)

displayScore()

if gameState == ’start’ then


love.graphics.setBackgroundColor(0, 1, 0)
love.graphics.setFont(smallFont)
love.graphics.printf(’Welcome to Pong!’, 0, 10, VIRTUAL_WIDTH, ’center’)
love.graphics.printf(’Press Enter to begin!’, 0, 20, VIRTUAL_WIDTH, ’center’)
elseif gameState == ’serve’ then
love.graphics.setBackgroundColor(0, 1, 0)
love.graphics.setFont(smallFont)
love.graphics.printf(’Player ’ .. tostring(servingPlayer) .. "’s serve!",
0, 10, VIRTUAL_WIDTH, ’center’)
love.graphics.printf(’Press Enter to serve!’, 0, 20, VIRTUAL_WIDTH, ’center’)
elseif gameState == ’play’ then
love.graphics.setBackgroundColor(0, 1, 0)

elseif gameState == ’done’ then


love.graphics.setBackgroundColor(1, 0, 0)
love.graphics.setFont(largeFont)
love.graphics.setColor(0, 1, 0)

Department of Computer Science 30


Christ College(Autonomous) Game Development

love.graphics.printf(’Player --’ .. tostring(winningPlayer) .. ’--wins!!’, 0, 10, VIRTUAL_WI


love.graphics.setFont(smallFont)
love.graphics.printf(’Press enter to restart’, 0, 50, VIRTUAL_WIDTH, ’center’)
end

player1:render()
player2:render()
ball:render()

displayFPS()

push:apply(’end’)
end

function displayFPS()

love.graphics.setFont(fpsFont)
love.graphics.print(’FPS: ’ .. tostring(love.timer.getFPS()), 10, 10)
end

function displayScore()

love.graphics.setFont(scoreFont)
love.graphics.print(tostring(player1Score), VIRTUAL_WIDTH / 2 - 50,
VIRTUAL_HEIGHT / 3)
love.graphics.print(tostring(player2Score), VIRTUAL_WIDTH / 2 + 30,
VIRTUAL_HEIGHT / 3)
end

class.lua

--[[
Copyright (c) 2010-2013 Matthias Richter
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization.

Department of Computer Science 31


Christ College(Autonomous) Game Development

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]--

local function include_helper(to, from, seen)


if from == nil then
return to
elseif type(from) ~= ’table’ then
return from
elseif seen[from] then
return seen[from]
end

seen[from] = to
for k,v in pairs(from) do
k = include_helper({}, k, seen) -- keys might also be tables
if to[k] == nil then
to[k] = include_helper({}, v, seen)
end
end
return to
end

-- deeply copies ‘other’ into ‘class’. keys in ‘other’ that are already
-- defined in ‘class’ are omitted
local function include(class, other)
return include_helper(class, other, {})
end

-- returns a deep copy of ‘other’


local function clone(other)
return setmetatable(include({}, other), getmetatable(other))
end

local function new(class)


-- mixins
class = class or {} -- class can be nil
local inc = class.__includes or {}
if getmetatable(inc) then inc = {inc} end

for _, other in ipairs(inc) do

Department of Computer Science 32


Christ College(Autonomous) Game Development

if type(other) == "string" then


other = _G[other]
end
include(class, other)
end

-- class implementation
class.__index = class
class.init = class.init or class[1] or function() end
class.include = class.include or include
class.clone = class.clone or clone

-- constructor call
return setmetatable(class, {__call = function(c, ...)
local o = setmetatable({}, c)
o:init(...)
return o
end})
end

-- interface for cross class-system compatibility (see https://github.com/bartbes/Class-Comm


if class_commons ~= false and not common then
common = {}
function common.class(name, prototype, parent)
return new{__includes = {prototype, parent}}
end
function common.instance(class, ...)
return class(...)
end
end

-- the module
return setmetatable({new = new, include = include, clone = clone},
{__call = function(_,...) return new(...) end})

push.lua

-- push.lua v0.2

-- Copyright (c) 2017 Ulysse Ramage


-- Permission is hereby granted, free of charge, to any person obtaining a copy of this soft
-- The above copyright notice and this permission notice shall be included in all copies or
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLU

Department of Computer Science 33


Christ College(Autonomous) Game Development

local push = {

defaults = {
fullscreen = false,
resizable = false,
pixelperfect = false,
highdpi = true,
canvas = true
}

}
setmetatable(push, push)

--TODO: rendering resolution?


--TODO: clean up code

function push:applySettings(settings)
for k, v in pairs(settings) do
self["_" .. k] = v
end
end

function push:resetSettings() return self:applySettings(self.defaults) end

function push:setupScreen(WWIDTH, WHEIGHT, RWIDTH, RHEIGHT, settings)

settings = settings or {}

self._WWIDTH, self._WHEIGHT = WWIDTH, WHEIGHT


self._RWIDTH, self._RHEIGHT = RWIDTH, RHEIGHT

self:applySettings(self.defaults) --set defaults first


self:applySettings(settings) --then fill with custom settings

love.window.setMode( self._RWIDTH, self._RHEIGHT, {


fullscreen = self._fullscreen,
resizable = self._resizable,
highdpi = self._highdpi
} )

self:initValues()

if self._canvas then
self:setupCanvas({ "default" }) --setup canvas
end

Department of Computer Science 34


Christ College(Autonomous) Game Development

self._borderColor = {0, 0, 0}

self._drawFunctions = {
["start"] = self.start,
["end"] = self.finish
}

return self
end

function push:setupCanvas(canvases)
table.insert(canvases, { name = "_render" }) --final render

self._canvas = true
self.canvases = {}

for i = 1, #canvases do
self.canvases[i] = {
name = canvases[i].name,
shader = canvases[i].shader,
canvas = love.graphics.newCanvas(self._WWIDTH, self._WHEIGHT)
}
end

return self
end

function push:setCanvas(name)
if not self._canvas then return true end
return love.graphics.setCanvas( self:getCanvasTable(name).canvas )
end
function push:getCanvasTable(name)
for i = 1, #self.canvases do
if self.canvases[i].name == name then
return self.canvases[i]
end
end
end
function push:setShader(name, shader)
if not shader then
self:getCanvasTable("_render").shader = name
else
self:getCanvasTable(name).shader = shader
end
end

Department of Computer Science 35


Christ College(Autonomous) Game Development

function push:initValues()
self._PSCALE = self._highdpi and love.window.getDPIScale() or 1

self._SCALE = {
x = self._RWIDTH/self._WWIDTH * self._PSCALE,
y = self._RHEIGHT/self._WHEIGHT * self._PSCALE
}

if self._stretched then --if stretched, no need to apply offset


self._OFFSET = {x = 0, y = 0}
else
local scale = math.min(self._SCALE.x, self._SCALE.y)
if self._pixelperfect then scale = math.floor(scale) end

self._OFFSET = {x = (self._SCALE.x - scale) * (self._WWIDTH/2), y = (self._SCALE.y - scale)


self._SCALE.x, self._SCALE.y = scale, scale --apply same scale to X and Y
end

self._GWIDTH = self._RWIDTH * self._PSCALE - self._OFFSET.x * 2


self._GHEIGHT = self._RHEIGHT * self._PSCALE - self._OFFSET.y * 2
end

--[[ DEPRECATED ]]--


function push:apply(operation, shader)
if operation == "start" then
self:start()
elseif operation == "finish" or operation == "end" then
self:finish(shader)
end
end

function push:start()
if self._canvas then
love.graphics.push()
love.graphics.setCanvas(self.canvases[1].canvas)
else
love.graphics.translate(self._OFFSET.x, self._OFFSET.y)
love.graphics.setScissor(self._OFFSET.x, self._OFFSET.y, self._WWIDTH*self._SCALE.x, self._W
love.graphics.push()
love.graphics.scale(self._SCALE.x, self._SCALE.y)
end
end

function push:finish(shader)
love.graphics.setBackgroundColor(unpack(self._borderColor))
if self._canvas then

Department of Computer Science 36


Christ College(Autonomous) Game Development

local _render = self:getCanvasTable("_render")

love.graphics.pop()

love.graphics.setColor(255, 255, 255)

--draw canvas
love.graphics.setCanvas(_render.canvas)
for i = 1, #self.canvases - 1 do --do not draw _render yet
local _table = self.canvases[i]
love.graphics.setShader(_table.shader)
love.graphics.draw(_table.canvas)
end
love.graphics.setCanvas()

--draw render
love.graphics.translate(self._OFFSET.x, self._OFFSET.y)
love.graphics.setShader(shader or self:getCanvasTable("_render").shader)
love.graphics.draw(self:getCanvasTable("_render").canvas, 0, 0, 0, self._SCALE.x, self._SCAL

--clear canvas
for i = 1, #self.canvases do
love.graphics.setCanvas( self.canvases[i].canvas )
love.graphics.clear()
end

love.graphics.setCanvas()
love.graphics.setShader()
else
love.graphics.pop()
love.graphics.setScissor()
end
end

function push:setBorderColor(color, g, b)
self._borderColor = g and {color, g, b} or color
end

function push:toGame(x, y)
x, y = x - self._OFFSET.x, y - self._OFFSET.y
local normalX, normalY = x / self._GWIDTH, y / self._GHEIGHT

x = (x >= 0 and x <= self._WWIDTH * self._SCALE.x) and normalX * self._WWIDTH or nil


y = (y >= 0 and y <= self._WHEIGHT * self._SCALE.y) and normalY * self._WHEIGHT or nil

return x, y

Department of Computer Science 37


Christ College(Autonomous) Game Development

end

--doesn’t work - TODO


function push:toReal(x, y)
return x+self._OFFSET.x, y+self._OFFSET.y
end

function push:switchFullscreen(winw, winh)


self._fullscreen = not self._fullscreen
local windowWidth, windowHeight = love.window.getDesktopDimensions()

if self._fullscreen then --save windowed dimensions for later


self._WINWIDTH, self._WINHEIGHT = self._RWIDTH, self._RHEIGHT
elseif not self._WINWIDTH or not self._WINHEIGHT then
self._WINWIDTH, self._WINHEIGHT = windowWidth * .5, windowHeight * .5
end

self._RWIDTH = self._fullscreen and windowWidth or winw or self._WINWIDTH


self._RHEIGHT = self._fullscreen and windowHeight or winh or self._WINHEIGHT

self:initValues()

love.window.setFullscreen(self._fullscreen, "desktop")
if not self._fullscreen and (winw or winh) then
love.window.setMode(self._RWIDTH, self._RHEIGHT) --set window dimensions
end
end

function push:resize(w, h)
local pixelScale = love.window.getDPIScale()
if self._highdpi then w, h = w / pixelScale, h / pixelScale end
self._RWIDTH = w
self._RHEIGHT = h
self:initValues()
end

function push:getWidth() return self._WWIDTH end


function push:getHeight() return self._WHEIGHT end
function push:getDimensions() return self._WWIDTH, self._WHEIGHT end

return push

Ball.lua

[verbetim]
--[[

Department of Computer Science 38


Christ College(Autonomous) Game Development

GD50 2018
Pong Remake
-- Ball Class --
Author: Colton Ogden
[email protected]
Represents a ball which will bounce back and forth between paddles
and walls until it passes a left or right boundary of the screen,
scoring a point for the opponent.
]]

Ball = Class{}

function Ball:init(x, y, width, height)


self.x = x
self.y = y
self.width = width
self.height = height

-- these variables are for keeping track of our velocity on both the
-- X and Y axis, since the ball can move in two dimensions
self.dy = math.random(2) == 1 and -100 or 100
self.dx = math.random(2) == 1 and math.random(-80, -100) or math.random(80, 100)
end

--[[
Expects a paddle as an argument and returns true or false, depending
on whether their rectangles overlap.
]]
function Ball:collides(paddle)
-- first, check to see if the left edge of either is farther to the right
-- than the right edge of the other
if self.x > paddle.x + paddle.width or paddle.x > self.x + self.width then
return false
end

-- then check to see if the bottom edge of either is higher than the top
-- edge of the other
if self.y > paddle.y + paddle.height or paddle.y > self.y + self.height then
return false
end

-- if the above aren’t true, they’re overlapping


return true
end

--[[

Department of Computer Science 39


Christ College(Autonomous) Game Development

Places the ball in the middle of the screen, with an initial random velocity
on both axes.
]]
function Ball:reset()
self.x = VIRTUAL_WIDTH / 2 - 2
self.y = VIRTUAL_HEIGHT / 2 - 2
self.dy = math.random(2) == 1 and -100 or 100
self.dx = math.random(-50, 50)
end

--[[
Simply applies velocity to position, scaled by deltaTime.
]]
function Ball:update(dt)
self.x = self.x + self.dx * dt
self.y = self.y + self.dy * dt
end

function Ball:render()
love.graphics.setColor(1, 0, 0)
love.graphics.rectangle(’fill’, self.x, self.y, self.width, self.height)
end

Paddle.lua

Paddle = Class{}

--[[
The ‘init‘ function on our class is called just once, when the object
is first created. Used to set up all variables in the class and get it
ready for use.
Our Paddle should take an X and a Y, for positioning, as well as a width
and height for its dimensions.
Note that ‘self‘ is a reference to *this* object, whichever object is
instantiated at the time this function is called. Different objects can
have their own x, y, width, and height values, thus serving as containers
for data. In this sense, they’re very similar to structs in C.
]]
function Paddle:init(x, y, width, height)
self.x = x
self.y = y
self.width = width
self.height = height
self.dy = 0
end

Department of Computer Science 40


Christ College(Autonomous) Game Development

function Paddle:update(dt)
-- math.max here ensures that we’re the greater of 0 or the player’s
-- current calculated Y position when pressing up so that we don’t
-- go into the negatives; the movement calculation is simply our
-- previously-defined paddle speed scaled by dt
if self.dy < 0 then
self.y = math.max(0, self.y + self.dy * dt)
-- similar to before, this time we use math.min to ensure we don’t
-- go any farther than the bottom of the screen minus the paddle’s
-- height (or else it will go partially below, since position is
-- based on its top left corner)
else
self.y = math.min(VIRTUAL_HEIGHT - self.height, self.y + self.dy * dt)
end
end

--[[
To be called by our main function in ‘love.draw‘, ideally. Uses
LÖVE2D’s ‘rectangle‘ function, which takes in a draw mode as the first
argument as well as the position and dimensions for the rectangle. To
change the color, one must call ‘love.graphics.setColor‘. As of the
newest version of LÖVE2D, you can even draw rounded rectangles!
]]
function Paddle:render()
love.graphics.rectangle(’fill’, self.x, self.y, self.width, self.height)
end

B.2 Mr.Toad
main.lua
[breaklines=true]
push = require ’push’

-- the "Class" library we’re using will allow us to represent anything in


-- our game as code, rather than keeping track of many disparate variables and
-- methods
--
-- https://github.com/vrld/hump/blob/master/class.lua
Class = require ’class’

-- a basic StateMachine class which will allow us to transition to and from


-- game states smoothly and avoid monolithic code in one file
require ’StateMachine’

Department of Computer Science 41


Christ College(Autonomous) Game Development

require ’states/BaseState’
require ’states/CountdownState’
require ’states/PlayState’
require ’states/ScoreState’
require ’states/TitleScreenState’

require ’Bird’
require ’Pipe’
require ’PipePair’

-- physical screen dimensions


WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720

-- virtual resolution dimensions


VIRTUAL_WIDTH = 512
VIRTUAL_HEIGHT = 288

local backgroundScroll = 0

local ground = love.graphics.newImage(’ground.png’)


local groundScroll = 0

local BACKGROUND_SCROLL_SPEED = 30
local GROUND_SCROLL_SPEED = 60

local BACKGROUND_LOOPING_POINT = 413

-- global variable we can use to scroll the map


scrolling = true

function love.load()
-- initialize our nearest-neighbor filter
love.graphics.setDefaultFilter(’nearest’, ’nearest’)

-- seed the RNG


math.randomseed(os.time())

-- app window title


love.window.setTitle(’Mr. Toad’)

-- initialize our nice-looking retro text fonts


smallFont = love.graphics.newFont(’font.ttf’, 8)
mediumFont = love.graphics.newFont(’flappy.ttf’, 14)
flappyFont = love.graphics.newFont(’flappy.ttf’, 28)
hugeFont = love.graphics.newFont(’flappy.ttf’, 56)

Department of Computer Science 42


Christ College(Autonomous) Game Development

love.graphics.setFont(flappyFont)

-- initialize our table of sounds


sounds = {
[’jump’] = love.audio.newSource(’jump.wav’, ’static’),
[’explosion’] = love.audio.newSource(’explosion.wav’, ’static’),
[’hurt’] = love.audio.newSource(’hurt.wav’, ’static’),
[’score’] = love.audio.newSource(’score.wav’, ’static’),

-- https://freesound.org/people/xsgianni/sounds/388079/
[’music’] = love.audio.newSource(’marios_way.mp3’, ’static’)
}

-- kick off music


sounds[’music’]:setLooping(true)
sounds[’music’]:play()

-- initialize our virtual resolution


push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, {
vsync = true,
fullscreen = false,
resizable = true
})

-- initialize state machine with all state-returning functions


gStateMachine = StateMachine {
[’title’] = function() return TitleScreenState() end,
[’countdown’] = function() return CountdownState() end,
[’play’] = function() return PlayState() end,
[’score’] = function() return ScoreState() end
}
gStateMachine:change(’title’)

-- initialize input table


love.keyboard.keysPressed = {}

-- initialize mouse input table


love.mouse.buttonsPressed = {}
end

function love.resize(w, h)
push:resize(w, h)
end

function love.keypressed(key)
-- add to our table of keys pressed this frame

Department of Computer Science 43


Christ College(Autonomous) Game Development

love.keyboard.keysPressed[key] = true

if key == ’escape’ then


love.event.quit()
end
end

--[[
LÖVE2D callback fired each time a mouse button is pressed; gives us the
X and Y of the mouse, as well as the button in question.
]]
function love.mousepressed(x, y, button)
love.mouse.buttonsPressed[button] = true
end

function love.keyboard.wasPressed(key)
return love.keyboard.keysPressed[key]
end

--[[
Equivalent to our keyboard function from before, but for the mouse buttons.
]]
function love.mouse.wasPressed(button)
return love.mouse.buttonsPressed[button]
end

function love.update(dt)
if scrolling then
backgroundScroll = (backgroundScroll + BACKGROUND_SCROLL_SPEED * dt) % BACKGROUND_LOOPING_PO
groundScroll = (groundScroll + GROUND_SCROLL_SPEED * dt) % VIRTUAL_WIDTH
end

gStateMachine:update(dt)

love.keyboard.keysPressed = {}
love.mouse.buttonsPressed = {}
end

function love.draw()
push:start()

love.graphics.draw(background, -backgroundScroll, 0)
gStateMachine:render()
love.graphics.draw(ground, -groundScroll, VIRTUAL_HEIGHT - 16)

push:finish()

Department of Computer Science 44


Christ College(Autonomous) Game Development

end

class.lua

--[[
Copyright (c) 2010-2013 Matthias Richter

Permission is hereby granted, free of charge, to any person obtaining a copy


of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]--

local function include_helper(to, from, seen)


if from == nil then
return to
elseif type(from) ~= ’table’ then
return from
elseif seen[from] then
return seen[from]
end

seen[from] = to
for k,v in pairs(from) do
k = include_helper({}, k, seen) -- keys might also be tables
if to[k] == nil then
to[k] = include_helper({}, v, seen)
end

Department of Computer Science 45


Christ College(Autonomous) Game Development

end
return to
end

-- deeply copies ‘other’ into ‘class’. keys in ‘other’ that are already
-- defined in ‘class’ are omitted
local function include(class, other)
return include_helper(class, other, {})
end

-- returns a deep copy of ‘other’


local function clone(other)
return setmetatable(include({}, other), getmetatable(other))
end

local function new(class)


-- mixins
class = class or {} -- class can be nil
local inc = class.__includes or {}
if getmetatable(inc) then inc = {inc} end

for _, other in ipairs(inc) do


if type(other) == "string" then
other = _G[other]
end
include(class, other)
end

-- class implementation
class.__index = class
class.init = class.init or class[1] or function() end
class.include = class.include or include
class.clone = class.clone or clone

-- constructor call
return setmetatable(class, {__call = function(c, ...)
local o = setmetatable({}, c)
o:init(...)
return o
end})
end

-- interface for cross class-system compatibility (see https://github.com/bartbes/Class-Comm


if class_commons ~= false and not common then
common = {}
function common.class(name, prototype, parent)

Department of Computer Science 46


Christ College(Autonomous) Game Development

return new{__includes = {prototype, parent}}


end
function common.instance(class, ...)
return class(...)
end
end

-- the module
return setmetatable({new = new, include = include, clone = clone},
{__call = function(_,...) return new(...) end})

push.lua

-- push.lua v0.4

-- Copyright (c) 2020 Ulysse Ramage


-- Permission is hereby granted, free of charge, to any person obtaining a copy of this soft
-- The above copyright notice and this permission notice shall be included in all copies or
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLU

local love11 = love.getVersion() == 11


local getDPI = love11 and love.window.getDPIScale or love.window.getPixelScale
local windowUpdateMode = love11 and love.window.updateMode or function(width, height, settin
local _, _, flags = love.window.getMode()
for k, v in pairs(settings) do flags[k] = v end
love.window.setMode(width, height, flags)
end

local push = {

defaults = {
fullscreen = false,
resizable = false,
pixelperfect = false,
highdpi = true,
canvas = true,
stencil = true
}

}
setmetatable(push, push)

function push:applySettings(settings)

Department of Computer Science 47


Christ College(Autonomous) Game Development

for k, v in pairs(settings) do
self["_" .. k] = v
end
end

function push:resetSettings() return self:applySettings(self.defaults) end

function push:setupScreen(WWIDTH, WHEIGHT, RWIDTH, RHEIGHT, settings)

settings = settings or {}

self._WWIDTH, self._WHEIGHT = WWIDTH, WHEIGHT


self._RWIDTH, self._RHEIGHT = RWIDTH, RHEIGHT

self:applySettings(self.defaults) --set defaults first


self:applySettings(settings) --then fill with custom settings

windowUpdateMode(self._RWIDTH, self._RHEIGHT, {
fullscreen = self._fullscreen,
resizable = self._resizable,
highdpi = self._highdpi
})

self:initValues()

if self._canvas then
self:setupCanvas({ "default" }) --setup canvas
end

self._borderColor = {0, 0, 0}

self._drawFunctions = {
["start"] = self.start,
["end"] = self.finish
}

return self
end

function push:setupCanvas(canvases)
table.insert(canvases, { name = "_render", private = true }) --final render

self._canvas = true
self.canvases = {}

for i = 1, #canvases do

Department of Computer Science 48


Christ College(Autonomous) Game Development

push:addCanvas(canvases[i])
end

return self
end
function push:addCanvas(params)
table.insert(self.canvases, {
name = params.name,
private = params.private,
shader = params.shader,
canvas = love.graphics.newCanvas(self._WWIDTH, self._WHEIGHT),
stencil = params.stencil or self._stencil
})
end

function push:setCanvas(name)
if not self._canvas then return true end
local canvasTable = self:getCanvasTable(name)
return love.graphics.setCanvas({ canvasTable.canvas, stencil = canvasTable.stencil })
end
function push:getCanvasTable(name)
for i = 1, #self.canvases do
if self.canvases[i].name == name then
return self.canvases[i]
end
end
end
function push:setShader(name, shader)
if not shader then
self:getCanvasTable("_render").shader = name
else
self:getCanvasTable(name).shader = shader
end
end

function push:initValues()
self._PSCALE = (not love11 and self._highdpi) and getDPI() or 1

self._SCALE = {
x = self._RWIDTH/self._WWIDTH * self._PSCALE,
y = self._RHEIGHT/self._WHEIGHT * self._PSCALE
}

if self._stretched then --if stretched, no need to apply offset


self._OFFSET = {x = 0, y = 0}
else

Department of Computer Science 49


Christ College(Autonomous) Game Development

local scale = math.min(self._SCALE.x, self._SCALE.y)


if self._pixelperfect then scale = math.floor(scale) end

self._OFFSET = {x = (self._SCALE.x - scale) * (self._WWIDTH/2), y = (self._SCALE.y - scale)


self._SCALE.x, self._SCALE.y = scale, scale --apply same scale to X and Y
end

self._GWIDTH = self._RWIDTH * self._PSCALE - self._OFFSET.x * 2


self._GHEIGHT = self._RHEIGHT * self._PSCALE - self._OFFSET.y * 2
end

function push:apply(operation, shader)


self._drawFunctions[operation](self, shader)
end

function push:start()
if self._canvas then
love.graphics.push()
love.graphics.setCanvas({ self.canvases[1].canvas, stencil = self.canvases[1].stencil })

else
love.graphics.translate(self._OFFSET.x, self._OFFSET.y)
love.graphics.setScissor(self._OFFSET.x, self._OFFSET.y, self._WWIDTH*self._SCALE.x, self._W
love.graphics.push()
love.graphics.scale(self._SCALE.x, self._SCALE.y)
end
end

function push:applyShaders(canvas, shaders)


local _shader = love.graphics.getShader()
if #shaders <= 1 then
love.graphics.setShader(shaders[1])
love.graphics.draw(canvas)
else
local _canvas = love.graphics.getCanvas()

local _tmp = self:getCanvasTable("_tmp")


if not _tmp then --create temp canvas only if needed
self:addCanvas({ name = "_tmp", private = true, shader = nil })
_tmp = self:getCanvasTable("_tmp")
end

love.graphics.push()
love.graphics.origin()
local outputCanvas
for i = 1, #shaders do

Department of Computer Science 50


Christ College(Autonomous) Game Development

local inputCanvas = i % 2 == 1 and canvas or _tmp.canvas


outputCanvas = i % 2 == 0 and canvas or _tmp.canvas
love.graphics.setCanvas(outputCanvas)
love.graphics.clear()
love.graphics.setShader(shaders[i])
love.graphics.draw(inputCanvas)
love.graphics.setCanvas(inputCanvas)
end
love.graphics.pop()

love.graphics.setCanvas(_canvas)
love.graphics.draw(outputCanvas)
end
love.graphics.setShader(_shader)
end

function push:finish(shader)
love.graphics.setBackgroundColor(unpack(self._borderColor))
if self._canvas then
local _render = self:getCanvasTable("_render")

love.graphics.pop()

local white = love11 and 1 or 255


love.graphics.setColor(white, white, white)

--draw canvas
love.graphics.setCanvas(_render.canvas)
for i = 1, #self.canvases do --do not draw _render yet
local _table = self.canvases[i]
if not _table.private then
local _canvas = _table.canvas
local _shader = _table.shader
self:applyShaders(_canvas, type(_shader) == "table" and _shader or { _shader })
end
end
love.graphics.setCanvas()

--draw render
love.graphics.translate(self._OFFSET.x, self._OFFSET.y)
local shader = shader or _render.shader
love.graphics.push()
love.graphics.scale(self._SCALE.x, self._SCALE.y)
self:applyShaders(_render.canvas, type(shader) == "table" and shader or { shader })
love.graphics.pop()

Department of Computer Science 51


Christ College(Autonomous) Game Development

--clear canvas
for i = 1, #self.canvases do
love.graphics.setCanvas(self.canvases[i].canvas)
love.graphics.clear()
end

love.graphics.setCanvas()
love.graphics.setShader()
else
love.graphics.pop()
love.graphics.setScissor()
end
end

function push:setBorderColor(color, g, b)
self._borderColor = g and {color, g, b} or color
end

function push:toGame(x, y)
x, y = x - self._OFFSET.x, y - self._OFFSET.y
local normalX, normalY = x / self._GWIDTH, y / self._GHEIGHT

x = (x >= 0 and x <= self._WWIDTH * self._SCALE.x) and normalX * self._WWIDTH or nil


y = (y >= 0 and y <= self._WHEIGHT * self._SCALE.y) and normalY * self._WHEIGHT or nil

return x, y
end

--doesn’t work - TODO


function push:toReal(x, y)
return x + self._OFFSET.x, y + self._OFFSET.y
end

function push:switchFullscreen(winw, winh)


self._fullscreen = not self._fullscreen
local windowWidth, windowHeight = love.window.getDesktopDimensions()

if self._fullscreen then --save windowed dimensions for later


self._WINWIDTH, self._WINHEIGHT = self._RWIDTH, self._RHEIGHT
elseif not self._WINWIDTH or not self._WINHEIGHT then
self._WINWIDTH, self._WINHEIGHT = windowWidth * .5, windowHeight * .5
end

self._RWIDTH = self._fullscreen and windowWidth or winw or self._WINWIDTH


self._RHEIGHT = self._fullscreen and windowHeight or winh or self._WINHEIGHT

Department of Computer Science 52


Christ College(Autonomous) Game Development

self:initValues()

love.window.setFullscreen(self._fullscreen, "desktop")
if not self._fullscreen and (winw or winh) then
windowUpdateMode(self._RWIDTH, self._RHEIGHT) --set window dimensions
end
end

function push:resize(w, h)
if self._highdpi then w, h = w / self._PSCALE, h / self._PSCALE end
self._RWIDTH = w
self._RHEIGHT = h
self:initValues()
end

function push:getWidth() return self._WWIDTH end


function push:getHeight() return self._WHEIGHT end
function push:getDimensions() return self._WWIDTH, self._WHEIGHT end

return push

pipe.lua

[verbetim]
--[[
Pipe Class
Author: Colton Ogden
[email protected]

The Pipe class represents the pipes that randomly spawn in our game, which act as our primar
The pipes can stick out a random distance from the top or bottom of the screen. When the pla
with one of them, it’s game over. Rather than our bird actually moving through the screen ho
the pipes themselves scroll through the game to give the illusion of player movement.
]]

Pipe = Class{}

-- since we only want the image loaded once, not per instantation, define it externally
local PIPE_IMAGE = love.graphics.newImage(’pipe.png’)

function Pipe:init(orientation, y)
self.x = VIRTUAL_WIDTH + 64
self.y = y

self.width = PIPE_WIDTH

Department of Computer Science 53


Christ College(Autonomous) Game Development

self.height = PIPE_HEIGHT

self.orientation = orientation
end

function Pipe:update(dt)

end

function Pipe:render()
love.graphics.draw(PIPE_IMAGE, self.x,
(self.orientation == ’top’ and self.y + PIPE_HEIGHT or self.y),
0, 1, self.orientation == ’top’ and -1 or 1)
end

pipepair.lua

--[[
PipePair Class

Author: Colton Ogden


[email protected]

Used to represent a pair of pipes that stick together as they scroll, providing an opening
for the player to jump through in order to score a point.
]]

PipePair = Class{}

-- size of the gap between pipes


local GAP_HEIGHT = 100

function PipePair:init(y)
-- flag to hold whether this pair has been scored (jumped through)
self.scored = false

-- initialize pipes past the end of the screen


self.x = VIRTUAL_WIDTH + 32

-- y value is for the topmost pipe; gap is a vertical shift of the second lower pipe
self.y = y

-- instantiate two pipes that belong to this pair


self.pipes = {
[’upper’] = Pipe(’top’, self.y),

Department of Computer Science 54


Christ College(Autonomous) Game Development

[’lower’] = Pipe(’bottom’, self.y + PIPE_HEIGHT + GAP_HEIGHT)


}

-- whether this pipe pair is ready to be removed from the scene


self.remove = false
end

function PipePair:update(dt)
-- remove the pipe from the scene if it’s beyond the left edge of the screen,
-- else move it from right to left
if self.x > -PIPE_WIDTH then
self.x = self.x - PIPE_SPEED * dt
self.pipes[’lower’].x = self.x
self.pipes[’upper’].x = self.x
else
self.remove = true
end
end

function PipePair:render()
for l, pipe in pairs(self.pipes) do
pipe:render()
end
end

bird.lua

--[[
Bird Class
Author: Colton Ogden
[email protected]

The Bird is what we control in the game via clicking or the space bar; whenever we press eit
the bird will flap and go up a little bit, where it will then be affected by gravity. If the
the ground or a pipe, the game is over.
]]

Bird = Class{}

local GRAVITY = 20

function Bird:init()
self.image = love.graphics.newImage(’frog3.png’)
self.x = VIRTUAL_WIDTH / 2 - 8
self.y = VIRTUAL_HEIGHT / 2 - 8

Department of Computer Science 55


Christ College(Autonomous) Game Development

self.width = self.image:getWidth()
self.height = self.image:getHeight()

self.dy = 0
end

--[[
AABB collision that expects a pipe, which will have an X and Y and reference
global pipe width and height values.
]]
function Bird:collides(pipe)
-- the 2’s are left and top offsets
-- the 4’s are right and bottom offsets
-- both offsets are used to shrink the bounding box to give the player
-- a little bit of leeway with the collision
if (self.x + 2) + (self.width - 4) >= pipe.x and self.x + 2 <= pipe.x + PIPE_WIDTH then
if (self.y + 2) + (self.height - 4) >= pipe.y and self.y + 2 <= pipe.y + PIPE_HEIGHT then
return true
end
end

return false
end

function Bird:update(dt)
self.dy = self.dy + GRAVITY * dt

if love.keyboard.wasPressed(’space’) or love.mouse.wasPressed(1) then


self.dy = -5
sounds[’jump’]:play()
end

self.y = self.y + self.dy


end

function Bird:render()
love.graphics.draw(self.image, self.x, self.y)
end

Department of Computer Science 56

You might also like