Love2d: Haxe: Ray-circle intersection test

By user request on Love2d IRC channel, yesterday I've made this nice function to do intersection/collision check between a ray (for clearance, here, a ray is a infinite line with starting point but no end point) and a circle.

Underlying code is fairly simple, though it does not even require understanding to use the function.

Love2d version takes advantage of multi-return values.
Haxe version has slightly longer code due for more optimal implementation of interface.

Download Haxe .hx Download Love2d .love

Snip:

--[[
Does a ray-circle intersection test.
Parameters:
	x1, y1, di - x, y, direction (radians) of ray
	x, y, r - position & radius of circle
Returns:
	result - whether collision occurred
	x - collision X
	y - collision Y
	distance - distance from ray start to collision point
]]
function ray2circle(x1, y1, di, x, y, r)
	local vx = math.cos(di)
	local vy = math.sin(di)
	
	-- get relative XY of circle (relative to ray origin):
	x = x - x1
	y = y - y1
	
	-- rotate it based on ray direction (as if ray starts at XY=0 and goes at +X):
	local tx = x * vx + y * vy
	local ty = x * vy + y * -vx
	
	-- clear misses:
	if (tx < -r) or (ty > r) or (ty < -r) then
		return false, nil, nil, nil
	end
	
	-- find X coordinate that line hits rotated circle at
	th = math.abs(math.cos(math.asin(ty / r))) * r
	
	-- too far behind
	if (tx + th < 0) then
		return false, nil, nil, nil
	end
	
	-- line start is inside the circle:
	tx = tx - th
	if (tx < 0) then
		return true, x1, y1, 0
	end
	
	--
	return true, x1 + tx * vx, y1 + tx * vy, tx
end

Love2d: Semi-turn-based platformer

A very rushed Haxe version to demonstrate how it looks in motion.
Does not necessarily represent features of love2d version in this post.

This was originally going to be a short reply-fix for a topic on love2d forum, but it seems that author did get somewhere with figuring that out on ones own, and I've quite overdone it in terms of a simple answer, so I formatted the code nicely, added several more features, and made this example.

Just in case above demonstration does not work, this example demonstrates a specific approach to game dynamic, where game logic occurs once per interval, while things are drawn and receive input at higher rate. I do not recall any actual platformer games that would use this principle, but a good example of such game is Snake (original grid-based version).
Example includes grid-to-point collision checking, actual specific platformer behaviour (with adjustable values), and value tweening (to make player movement nice & smooth).

Download (2KB .love)

Notepad++: Haxe syntax highlighting


Definition file in action, displaying syntax for function of fancy purpose.

In past few days I've spent some time to update an existing user definition file to UDL2, which was introduced in Notepad++ v6.2.

UDL2 improves possibilities of creating user defined languages slightly, introducing configurable delimiters, non-symbol operators, foldable comments, and other things.

For the case of Haxe, UDL2 improves detection of symbols, and made it possible to include hexadecimal number declarations, and separate highlighting for regular expressions. A thing that is currently missing out is preprocessor instructions (#if, #else, #end, ...), however, due to nature of these, highlighting is not always needed anyway.

Download

Update: Someone has set up a repository with a more up-to-date version of the UDL file, so you should take a look at that as well.

Alternatively, UDL .xml' contents:

<NotepadPlus>
    <UserLang name="Haxe" ext="hx" udlVersion="2.0">
        <Settings>
            <Global caseIgnored="no" allowFoldOfComments="yes" forceLineCommentsAtBOL="no" foldCompact="no" />
            <Prefix Keywords1="no" Keywords2="no" Keywords3="no" Keywords4="no" Keywords5="no" Keywords6="no" Keywords7="no" Keywords8="no" />
        </Settings>
        <KeywordLists>
            <Keywords name="Comments" id="0">00// 01 02 03/* 04*/</Keywords>
            <Keywords name="Numbers, additional" id="1"></Keywords>
            <Keywords name="Numbers, prefixes" id="2">0x</Keywords>
            <Keywords name="Numbers, extras with prefixes" id="3">a b c d e f A B C D E F</Keywords>
            <Keywords name="Numbers, suffixes" id="4"></Keywords>
            <Keywords name="Operators1" id="5">&apos; - ! &quot; $ &amp; ( ) , . : ; ? @ [ ] ^ ` | + &lt; = &gt; ~</Keywords>
            <Keywords name="Operators2" id="6"></Keywords>
            <Keywords name="Folders in code1, open" id="7">{</Keywords>
            <Keywords name="Folders in code1, middle" id="8"></Keywords>
            <Keywords name="Folders in code1, close" id="9">}</Keywords>
            <Keywords name="Folders in code2, open" id="10"></Keywords>
            <Keywords name="Folders in code2, middle" id="11"></Keywords>
            <Keywords name="Folders in code2, close" id="12"></Keywords>
            <Keywords name="Folders in comment, open" id="13">//{</Keywords>
            <Keywords name="Folders in comment, middle" id="14"></Keywords>
            <Keywords name="Folders in comment, close" id="15">//}</Keywords>
            <Keywords name="Keywords1" id="16">break callback case catch class continue default do else enum extends for function if implements import in interface new package return switch throw try typedef using var while</Keywords>
            <Keywords name="Keywords2" id="17">null true false</Keywords>
            <Keywords name="Keywords3" id="18">Void Int Float Dynamic Bool UInt Iterator Array List Hash IntHash Date String Xml</Keywords>
            <Keywords name="Keywords4" id="19">dynamic extern inline override private public static untyped cast trace super this arguments</Keywords>
            <Keywords name="Keywords5" id="20"></Keywords>
            <Keywords name="Keywords6" id="21"></Keywords>
            <Keywords name="Keywords7" id="22"></Keywords>
            <Keywords name="Keywords8" id="23"></Keywords>
            <Keywords name="Delimiters" id="24">00&apos; 01\ 02&apos; 03&quot; 04\ 05&quot; 06~/ 07\ 08/ 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23</Keywords>
        </KeywordLists>
        <Styles>
            <WordsStyle name="DEFAULT" styleID="0" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="COMMENTS" styleID="1" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="LINE COMMENTS" styleID="2" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="NUMBERS" styleID="3" fgColor="FA3232" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS1" styleID="4" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS2" styleID="5" fgColor="004080" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS3" styleID="6" fgColor="0080AA" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS4" styleID="7" fgColor="0064FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS5" styleID="8" fgColor="FF8040" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS6" styleID="9" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS7" styleID="10" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="KEYWORDS8" styleID="11" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="OPERATORS" styleID="12" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="FOLDER IN CODE1" styleID="13" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="FOLDER IN CODE2" styleID="14" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="FOLDER IN COMMENT" styleID="15" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS1" styleID="16" fgColor="A31515" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS2" styleID="17" fgColor="A31515" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS3" styleID="18" fgColor="7049B6" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS4" styleID="19" fgColor="000080" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS5" styleID="20" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS6" styleID="21" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS7" styleID="22" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
            <WordsStyle name="DELIMITERS8" styleID="23" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
        </Styles>
    </UserLang>
</NotepadPlus>

GameMaker: “flawed” AI path finding

In some cases, you may want object's AI to not pick exactly perfect path.

This example demonstrates creation of a basic "flawed" AI, that uses a rather plain method of finding path. Such will still make it reach destination in many cases, but will also allow player to "fool" the AI, making it stuck in dead ends or T-intersections (if player is standing right behind the wall).

To illustrate simplicity of concept, example is largely made in Drag & Drop.

Download

Continue reading

Transfer and update note

As you can see, some things changed around here, and there is everything missing.

This is a temporary effect, caused by fact that I've switched content management system from Chyrp to WordPress.

Pages will be re-added shortly.

Posts will be re-added more or less gradually.

This is a notable change, which will allow to improve some aspects of the website greatly.

Update: most of pages and data have been re-added, even with links kept. Now, slowly re-adding posts front-to-back.

Tululoo: Analog Control extension (updated)

Today I've updated my Tululoo example for analog controls.
If above image isn't very illustrative, these are small on-screen circles, that can be used in applications and games to convert user input from on-screen coordinate to a vector.
In contrast to not very documented example that I've made last spring, this is now presented as an extension.
That has detailed documentation, quite cleaner structure, and more functionality (for example, now it's possible to check if a specific analog control element was pressed, similar to keyboard keys).
As one can probably guess, it also handles touch input on mobile devices accordingly, allowing multiple controllers to be interacted with at once.

Download extension+example

GameMaker: Angular motion


It's like drifting. On a spaceship. In space.

This is an example of managing angular motion in GameMaker.
In turn, that means having angular speed with acceleration, friction, and limitation.
Such can be particularly useful for simulating a more 'smooth' rotation behaviour, when object will not start or stop rotating instantly.
If combined with relatively properly written code for linear motion, this can grant pretty nice behaviour for space games.
Also there's a "trail" effect added, originally just to demonstrate how it works.
Everything is pretty nice and simple.

Download GMK

GameMaker: Studio theme – GMGreen+

Today, instead of doing something possibly more interesting for a hour and some, I've spent those to edit standard theme that comes with GameMaker: Studio.

Modifications are as following:

  • Active window now has grey border, rather than a indefinitely green one.
  • Window captions now have a slight tilted line texture. Makes these a tiny bit less boring to look at.
  • Window control buttons are now better-spaced and cleaner.
  • Window border is now 3px instead of 4px, also with smaller amount of "rounding" on top of windows.
  • Fixed issue with 2-3 magenta pixels appearing near top-right corner when resizing MDI windows a lot.
  • Menu text is now of light-grey colour.
  • All sorts of buttons now have a grey colour for currently active one, and easier to distinguish green border for mouse-over.
  • Checkboxes now have an actual (non-triangular) "check"
  • Radio buttons are now properly anti-aliased.

I'll try to also include an icon file soon, but until then, a preferred method of installation is baking up of original "GMGreen.skn" and placing .skn from archive on it's place. Restarting GameMaker: Studio is required, obviously.

Download