Love Killa

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
_ex_
Citizen
Posts: 65
Joined: Thu Dec 08, 2011 2:59 pm

Love Killa

Post by _ex_ » Tue Apr 17, 2012 4:27 pm

Hi there!
so I was busy creating a new language based in Lua 5.2, it's called Killa ("moon" in Quechua)
it's almost ready for its 0.1 release and I was working closely with Love2d so it's integrated with Love 0.8.
At least my simple tetris clone is running on it.

The motive about this new language is that even when Lua is great I don't really like its syntaxis,
is that a valid reason to change a language? I think yes (if you can) :D
To be honest I even feel uneasy when I'm not programming with my own modified programming font.

So what is good about Killa? IMHO It has JavaScript like syntaxis, it forces you to declare your local or global variables and you can find typo errors,
(I found a minor bug in the code of graphics.lua), it supports +=, -=, *=, the ternary operator, JavaScript like fors, tables of index 0, and other minor details.
If there is interest in testing this language I can push my changes sooner that later.
To give you an idea of the feeling of the language here I'll post the Killa version of my simple tetris clone I did before:

Code: Select all

// Screen size
var SCREEN_WIDTH  = 480
var SCREEN_HEIGHT = 272

// Size of square tile
var TILE_SIZE = 12

// Board up-left corner coordinates
var BOARD_X = 180
var BOARD_Y = 4

// Preview tetromino position
var PREVIEW_X = 112
var PREVIEW_Y = 210

// Score position and length on screen
var SCORE_X      = 72
var SCORE_Y      = 52
var SCORE_LENGTH = 10

// Lines position and length on screen
var LINES_X      = 108
var LINES_Y      = 34
var LINES_LENGTH = 5

// Level position and length on screen
var LEVEL_X      = 108
var LEVEL_Y      = 16
var LEVEL_LENGTH = 5

// Tetromino subtotals position
var TETROMINO_X   = 425
var TETROMINO_L_Y = 53
var TETROMINO_I_Y = 77
var TETROMINO_T_Y = 101
var TETROMINO_S_Y = 125
var TETROMINO_Z_Y = 149
var TETROMINO_O_Y = 173
var TETROMINO_J_Y = 197

// Size of subtotals
var TETROMINO_LENGTH = 5

// Tetromino total position
var PIECES_X      = 418
var PIECES_Y      = 221
var PIECES_LENGTH = 6

// Size of number
var NUMBER_WIDTH  = 7
var NUMBER_HEIGHT = 9

var Platform = {
    m_bmpBackground: null;
    m_bmpBlocks: null;
    m_bmpNumbers: null;

    m_blocks: 0;
    m_numbers: 0;
}
global.Platform = Platform

var Game = global.Game
var love = global.love

// Initializes platform.
function Platform::init() {
    // Initialize random generator
    math.randomseed(os.time())

    // Load images.
    this.m_bmpBackground = love.graphics.newImage("back.png")

    this.m_bmpBlocks = love.graphics.newImage("blocks.png")
    this.m_bmpBlocks::setFilter("nearest", "nearest")
    var w = this.m_bmpBlocks::getWidth()
    var h = this.m_bmpBlocks::getHeight()

    // Create quads for blocks
    this.m_blocks = {}
    for each (var shadow = 0 to 1) {
        this.m_blocks[shadow] = {}
        for each (var color = 0 to Game.COLORS - 1) {
            this.m_blocks[shadow][color] = love.graphics.newQuad(TILE_SIZE * color, (TILE_SIZE + 1) * shadow,
                                                                        TILE_SIZE + 1, TILE_SIZE + 1, w, h)
        }
    }

    this.m_bmpNumbers = love.graphics.newImage("numbers.png")
    this.m_bmpNumbers::setFilter("nearest", "nearest")
    w = this.m_bmpNumbers::getWidth()
    h = this.m_bmpNumbers::getHeight()

    // Create quads for numbers
    this.m_numbers = {}
    for each (var color = 0 to Game.COLORS - 1) {
        this.m_numbers[color] = {}
        for each (var digit = 0 to 9) {
            this.m_numbers[color][digit] = love.graphics.newQuad(NUMBER_WIDTH * digit, NUMBER_HEIGHT * color,
                                                                 NUMBER_WIDTH, NUMBER_HEIGHT, w, h)
        }
    }
}

// Process events and notify game.
function Platform::onKeyDown(key) {
    if (key == "escape") {
        love.event.push("quit")
    }
    if ((key == "left") || (key == "a")) {
        Game::onEventStart(Game.Event.MOVE_LEFT)
    }
    if ((key == "right") || (key == "d")) {
        Game::onEventStart(Game.Event.MOVE_RIGHT)
    }
    if ((key == "down") || (key == "s")) {
        Game::onEventStart(Game.Event.MOVE_DOWN)
    }
    if ((key == "up") || (key == "w")) {
        Game::onEventStart(Game.Event.ROTATE_CW)
    }
    if (key == " ") {
        Game::onEventStart(Game.Event.DROP)
    }
    if (key == "f5") {
        Game::onEventStart(Game.Event.RESTART)
    }
    if (key == "f1") {
        Game::onEventStart(Game.Event.PAUSE)
    }
    if (key == "f2") {
        Game::onEventStart(Game.Event.SHOW_NEXT)
    }
    if (key == "f3") {
        Game::onEventStart(Game.Event.SHOW_SHADOW)
    }
}

function Platform::onKeyUp(key) {
    if ((key == "left") || (key == "a")) {
        Game::onEventEnd(Game.Event.MOVE_LEFT)
    }
    if ((key == "right") || (key == "d")) {
        Game::onEventEnd(Game.Event.MOVE_RIGHT)
    }
    if ((key == "down") || (key == "s")) {
        Game::onEventEnd(Game.Event.MOVE_DOWN)
    }
    if ((key == "up") || (key == "w")) {
        Game::onEventEnd(Game.Event.ROTATE_CW)
    }
}

// Draw a tile from a tetromino
function Platform::drawTile(x, y, tile, shadow) {
    love.graphics.drawq(this.m_bmpBlocks, this.m_blocks[shadow][tile], x, y)
}

// Draw a number on the given position
function Platform::drawNumber(x, y, number, length, color) {
    var pos = 0
    do {
        love.graphics.drawq(this.m_bmpNumbers, this.m_numbers[color][number % 10],
                            x + NUMBER_WIDTH * (length - pos), y)
        number = math.floor(number / 10)
        pos += 1
    } while (pos < length)
}

// Render the state of the game using platform functions.
function Platform::renderGame() {
    var i, j

    // Draw background
    love.graphics.draw(this.m_bmpBackground, 0, 0)

    // Draw preview block
    if (Game::showPreview()) {
        for (i = 0; i < Game.TETROMINO_SIZE; i += 1) {
            for (j = 0; j < Game.TETROMINO_SIZE; j += 1) {
                if (Game::nextBlock().cells[i][j] != Game.Cell.EMPTY) {
                    Platform::drawTile(PREVIEW_X + TILE_SIZE * i,
                                       PREVIEW_Y + TILE_SIZE * j,
                                       Game::nextBlock().cells[i][j], 0)
                }
            }
        }
    }

    // Draw shadow tetromino
    if (Game::showShadow() && Game::shadowGap() > 0) {
        for (i = 0; i < Game.TETROMINO_SIZE; i += 1) {
            for (j = 0; j < Game.TETROMINO_SIZE; j += 1) {
                if (Game::fallingBlock().cells[i][j] != Game.Cell.EMPTY) {
                    Platform::drawTile(BOARD_X + (TILE_SIZE * (Game::fallingBlock().x + i)),
                                      BOARD_Y + (TILE_SIZE * (Game::fallingBlock().y + Game::shadowGap() + j)),
                                      Game::fallingBlock().cells[i][j], 1)
                }
            }
        }
    }

    // Draw the cells in the board
    for (i = 0; i < Game.BOARD_TILEMAP_WIDTH; i += 1) {
        for (j = 0; j < Game.BOARD_TILEMAP_HEIGHT; j += 1) {
            if (Game::getCell(i, j) != Game.Cell.EMPTY) {
                Platform::drawTile(BOARD_X + (TILE_SIZE * i),
                                   BOARD_Y + (TILE_SIZE * j),
                                   Game::getCell(i, j), 0)
            }
        }
    }

    // Draw falling tetromino
    for (i = 0; i < Game.TETROMINO_SIZE; i += 1) {
        for (j = 0; j < Game.TETROMINO_SIZE; j += 1) {
            if (Game::fallingBlock().cells[i][j] != Game.Cell.EMPTY) {
                Platform::drawTile(BOARD_X + TILE_SIZE * (Game::fallingBlock().x + i),
                                   BOARD_Y + TILE_SIZE * (Game::fallingBlock().y + j),
                                   Game::fallingBlock().cells[i][j], 0)
            }
        }
    }

    // Draw game statistic data
    if (! Game::isPaused()) {
        Platform::drawNumber(LEVEL_X, LEVEL_Y, Game::stats().level, LEVEL_LENGTH, Game.Cell.WHITE)
        Platform::drawNumber(LINES_X, LINES_Y, Game::stats().lines, LINES_LENGTH, Game.Cell.WHITE)
        Platform::drawNumber(SCORE_X, SCORE_Y, Game::stats().score, SCORE_LENGTH, Game.Cell.WHITE)

        Platform::drawNumber(TETROMINO_X, TETROMINO_L_Y, Game::stats().pieces[Game.TetrominoType.L], TETROMINO_LENGTH, Game.Cell.ORANGE)
        Platform::drawNumber(TETROMINO_X, TETROMINO_I_Y, Game::stats().pieces[Game.TetrominoType.I], TETROMINO_LENGTH, Game.Cell.CYAN)
        Platform::drawNumber(TETROMINO_X, TETROMINO_T_Y, Game::stats().pieces[Game.TetrominoType.T], TETROMINO_LENGTH, Game.Cell.PURPLE)
        Platform::drawNumber(TETROMINO_X, TETROMINO_S_Y, Game::stats().pieces[Game.TetrominoType.S], TETROMINO_LENGTH, Game.Cell.GREEN)
        Platform::drawNumber(TETROMINO_X, TETROMINO_Z_Y, Game::stats().pieces[Game.TetrominoType.Z], TETROMINO_LENGTH, Game.Cell.RED)
        Platform::drawNumber(TETROMINO_X, TETROMINO_O_Y, Game::stats().pieces[Game.TetrominoType.O], TETROMINO_LENGTH, Game.Cell.YELLOW)
        Platform::drawNumber(TETROMINO_X, TETROMINO_J_Y, Game::stats().pieces[Game.TetrominoType.J], TETROMINO_LENGTH, Game.Cell.BLUE)

        Platform::drawNumber(PIECES_X, PIECES_Y, Game::stats().totalPieces, PIECES_LENGTH, Game.Cell.WHITE)
    }
}

function Platform::getSystemTime() {
    return math.floor(1000 * love.timer.getTime())
}

function Platform::random() {
    return math.random(1000000000)
}

EDIT: I was confusing the bug location in boot.lua
Last edited by _ex_ on Tue Apr 17, 2012 7:50 pm, edited 2 times in total.

User avatar
Davidobot
Party member
Posts: 1149
Joined: Sat Mar 31, 2012 5:18 am
Location: Game-Dev. Land
Contact:

Re: Love Killa

Post by Davidobot » Tue Apr 17, 2012 5:04 pm

Looks symple and amazing. Good job. :ultrahappy:
My library:
LovelyMoon

Check out my current project:
Raycaster

Oh hey, I have a website now!

User avatar
_ex_
Citizen
Posts: 65
Joined: Thu Dec 08, 2011 2:59 pm

Re: Love Killa

Post by _ex_ » Tue Apr 17, 2012 6:21 pm

thanks!

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Love Killa

Post by Robin » Tue Apr 17, 2012 6:58 pm

What bug was that you found in boot.lua?

You should probably add it to https://bitbucket.org/rude/love/issues.
Help us help you: attach a .love.

User avatar
_ex_
Citizen
Posts: 65
Joined: Thu Dec 08, 2011 2:59 pm

Re: Love Killa

Post by _ex_ » Tue Apr 17, 2012 7:31 pm

I'm sorry it was not in boot.lua but in graphics.lua, it's a minor bug I suspect:

Code: Select all

@@ -1351,7 +1351,7 @@
 			end
 		else
 			local t = type(value)
-			if t == "userdata" and value.type then t = valye.type end
+			if t == "userdata" and value.type then t = value.type end
 			error("Cannot send value (unsupported type: "..t..").")
 		end
 	end
notice the "valye" typo, I have corrected my original post, thanks!

Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests