How to change the image attribute of a capscreen using AUTOIT - image-processing

I am new to autoit and not sure how to change the brightness and contrast of the screencap before/after the image is saved on my harddrive? I found this function online (WinAPI_CreateColorAdjustment) but not sure how to integrate it with screencap.
My codes are:
#include <ScreenCapture.au3>
#include <GUIConstantsEx.au3>
$POSITION1=GUICtrlRead(1619)
$POSITION2=GUICtrlRead(210)
$POSITION3=GUICtrlRead(1900)
$POSITION4=GUICtrlRead(300)
_ScreenCapture_Capture(#ScriptDir & "\screencap.png",$POSITION1,$POSITION2,$POSITION3,$POSITION4)
Thanks a lot.

Here is an example for the _WinAPI_CreateColorAdjustment function:
#include <APIGdiConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GDIPlus.au3>
#include <GUIComboBox.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <SliderConstants.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIShPath.au3>
#include <WindowsConstants.au3>
Opt('GUICloseOnESC', 0)
Opt('TrayAutoPause', 0)
Global $g_aDefault[11] = [10000, 10000, 10000, 0, 10000, 0, 0, 0, 0, 0, 0]
Global $g_aAdjust = $g_aDefault
_GDIPlus_Startup()
Local $hObj, $hSrc, $W, $H, $sData
While 1
$sData = FileOpenDialog('Load Image', #ScriptDir & '\Extras', 'Image Files (*.bmp;*.dib;*.gif;*.jpg;*.tif)|All Files (*.*)', 1 + 2)
If #error Then Exit
$hObj = _GDIPlus_ImageLoadFromFile($sData)
If $hObj Then
$hSrc = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hObj)
$W = _GDIPlus_ImageGetWidth($hObj)
$H = _GDIPlus_ImageGetHeight($hObj)
_GDIPlus_ImageDispose($hObj)
If $hSrc Then
ExitLoop
EndIf
EndIf
MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Unable to load image.')
WEnd
Local $hForm = GUICreate(_WinAPI_PathStripPath($sData), $W, $H)
GUICtrlCreatePic('', 0, 0, $W, $H)
GUICtrlSetState(-1, $GUI_DISABLE)
Local $hPic = GUICtrlGetHandle(-1)
Global $g_hTool = GUICreate('Adjustments', 303, 484, -1, -1, BitOR($WS_CAPTION, $WS_POPUP), 0, $hForm)
GUICtrlCreateGraphic(0, 0, 303, 436)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlCreateGraphic(0, 436, 303, 1)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetBkColor(-1, 0xDFDFDF)
Global $g_aidSlider[9][6] = [[0, 0, 'Red', 25, 650, 100], [0, 0, 'Green', 25, 650, 100], [0, 0, 'Blue', 25, 650, 100], [0, 0, 'Black', 0, 400, 10], [0, 0, 'White', 600, 1000, 10], [0, 0, 'Contrast', -100, 100, 1], [0, 0, 'Brightness', -100, 100, 1], [0, 0, 'Colorfulness', -100, 100, 1], [0, 0, 'Tint', -100, 100, 1]]
For $i = 0 To 8
GUICtrlCreateLabel($g_aidSlider[$i][2] & ':', 10, 21 + $i * 31, 60, 14, $SS_RIGHT)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$g_aidSlider[$i][2] = GUICtrlCreateInput('', 243, 18 + $i * 31, 49, 19, BitOR($ES_CENTER, $ES_READONLY))
GUICtrlSetFont(-1, 9.3, 400, 0, 'Arial')
GUICtrlSetBkColor(-1, 0xFFFFFF)
$g_aidSlider[$i][0] = GUICtrlCreateSlider(71, 19 + $i * 31, 170, 20, BitOR($TBS_BOTH, $TBS_NOTICKS))
GUICtrlSetLimit(-1, $g_aidSlider[$i][4], $g_aidSlider[$i][3])
$g_aidSlider[$i][1] = GUICtrlGetHandle(-1)
GUICtrlSetBkColor(-1, 0xFFFFFF)
Next
GUICtrlCreateLabel('Illuminant:', 10, 310, 60, 14, $SS_RIGHT)
GUICtrlSetBkColor(-1, 0xFFFFFF)
Global $g_idCombo = GUICtrlCreateCombo('', 77, 306, 158, 160, $CBS_DROPDOWNLIST)
Local $aLight = StringSplit('Default|Tungsten lamp|Noon sunlight|NTSC daylight|Normal print|Bond paper print|Standard daylight|Northern daylight|Cool white lamp', '|')
For $i = 1 To $aLight[0]
_GUICtrlComboBox_AddString(-1, $aLight[$i])
Next
GUICtrlCreateLabel('Filters:', 10, 347, 60, 14, $SS_RIGHT)
GUICtrlSetBkColor(-1, 0xFFFFFF)
Global $g_aidCheck[3]
$g_aidCheck[0] = GUICtrlCreateCheckbox('Negative (invert colors)', 77, 343, 131, 21)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$g_aidCheck[1] = GUICtrlCreateCheckbox('Logarithmic', 77, 368, 76, 21)
GUICtrlSetBkColor(-1, 0xFFFFFF)
$g_aidCheck[2] = GUICtrlCreateCheckbox('Preview', 11, 401, 60, 21)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_CHECKED)
Local $aidButton[2]
$aidButton[0] = GUICtrlCreateButton('Reset', 136, 448, 75, 25)
$aidButton[1] = GUICtrlCreateButton('Save...', 218, 448, 75, 25)
_Reset()
GUICtrlSetState($g_aidSlider[0][0], $GUI_FOCUS)
GUIRegisterMsg($WM_HSCROLL, 'WM_HSCROLL')
GUISetState(#SW_SHOW, $hForm)
GUISetState(#SW_SHOW, $g_hTool)
While 1
Switch GUIGetMsg()
Case 0
ContinueLoop
Case $GUI_EVENT_CLOSE
Exit
Case $aidButton[0]
_Reset()
Case $aidButton[1]
GUISetState(#SW_DISABLE, $hForm)
$sData = FileSaveDialog('Save Image', #WorkingDir, 'Image Files (*.bmp;*.dib;*.gif;*.jpg;*.tif)|All Files (*.*)', 2 + 16, #ScriptDir & '\MyImage.jpg', $g_hTool)
GUICtrlSetState($aidButton[1], $GUI_FOCUS)
GUISetState(#SW_ENABLE, $hForm)
If Not $sData Then
ContinueLoop
EndIf
$hObj = _GDIPlus_BitmapCreateFromHBITMAP(_SendMessage($hPic, $STM_GETIMAGE))
If $hObj Then
If _GDIPlus_ImageSaveToFile($hObj, $sData) Then
$sData = 0
EndIf
_GDIPlus_ImageDispose($hObj)
EndIf
If $sData Then
MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Unable to save image.')
EndIf
Case $g_aidCheck[0]
If GUICtrlRead($g_aidCheck[0]) = $GUI_CHECKED Then
$g_aAdjust[9] = BitOR($g_aAdjust[9], $CA_NEGATIVE)
Else
$g_aAdjust[9] = BitAND($g_aAdjust[9], BitNOT($CA_NEGATIVE))
EndIf
_Update()
Case $g_aidCheck[1]
If GUICtrlRead($g_aidCheck[1]) = $GUI_CHECKED Then
$g_aAdjust[9] = BitOR($g_aAdjust[9], $CA_LOG_FILTER)
Else
$g_aAdjust[9] = BitAND($g_aAdjust[9], BitNOT($CA_LOG_FILTER))
EndIf
_Update()
Case $g_aidCheck[2]
If GUICtrlRead($g_aidCheck[2]) = $GUI_CHECKED Then
_SetBitmapAdjust($hPic, $hSrc, $g_aAdjust)
Else
_SetBitmapAdjust($hPic, $hSrc)
EndIf
Case $g_idCombo
$sData = _GUICtrlComboBox_GetCurSel($g_idCombo)
If $g_aAdjust[10] <> $sData Then
$g_aAdjust[10] = $sData
_Update()
EndIf
EndSwitch
WEnd
Func _Reset()
$g_aAdjust = $g_aDefault
For $i = 0 To 8
GUICtrlSetData($g_aidSlider[$i][0], $g_aAdjust[$i] / $g_aidSlider[$i][5])
GUICtrlSetData($g_aidSlider[$i][2], $g_aAdjust[$i])
Next
_GUICtrlComboBox_SetCurSel($g_idCombo, $g_aAdjust[10])
If BitAND($g_aAdjust[9], $CA_LOG_FILTER) Then
GUICtrlSetState($g_aidCheck[1], $GUI_CHECKED)
Else
GUICtrlSetState($g_aidCheck[1], $GUI_UNCHECKED)
EndIf
If BitAND($g_aAdjust[9], $CA_NEGATIVE) Then
GUICtrlSetState($g_aidCheck[0], $GUI_CHECKED)
Else
GUICtrlSetState($g_aidCheck[0], $GUI_UNCHECKED)
EndIf
_Update()
EndFunc ;==>_Reset
Func _SetBitmapAdjust($hWnd, $hBitmap, $aAdjust = 0)
If Not IsHWnd($hWnd) Then
$hWnd = GUICtrlGetHandle($hWnd)
If Not $hWnd Then
Return 0
EndIf
EndIf
Local $tAdjust = 0
If IsArray($aAdjust) Then
$tAdjust = _WinAPI_CreateColorAdjustment($aAdjust[9], $aAdjust[10], $aAdjust[0], $aAdjust[1], $aAdjust[2], $aAdjust[3], $aAdjust[4], $aAdjust[5], $aAdjust[6], $aAdjust[7], $aAdjust[8])
EndIf
$hBitmap = _WinAPI_AdjustBitmap($hBitmap, -1, -1, $HALFTONE, $tAdjust)
If #error Then
Return 0
EndIf
Local $hPrev = _SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap)
If $hPrev Then
_WinAPI_DeleteObject($hPrev)
EndIf
$hPrev = _SendMessage($hWnd, $STM_GETIMAGE)
If $hPrev <> $hBitmap Then
_WinAPI_DeleteObject($hBitmap)
EndIf
Return 1
EndFunc ;==>_SetBitmapAdjust
Func _Update()
If GUICtrlRead($g_aidCheck[2]) = $GUI_CHECKED Then
_SetBitmapAdjust($hPic, $hSrc, $g_aAdjust)
EndIf
EndFunc ;==>_Update
Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)
#forceref $iMsg, $wParam
Switch $hWnd
Case $g_hTool
For $i = 0 To 8
If $g_aidSlider[$i][1] = $lParam Then
$g_aAdjust[$i] = $g_aidSlider[$i][5] * GUICtrlRead($g_aidSlider[$i][0])
GUICtrlSetData($g_aidSlider[$i][2], $g_aAdjust[$i])
_Update()
ExitLoop
EndIf
Next
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_HSCROLL
Note: this function seems not work with PNG format, so you should save screenshots as JPG or BMP.

Related

how convert function byte to dart

i have a function like this in java
public static final byte[] f1504a = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70};
public static final byte[] bArr = {96, 50, (byte) 152, 96, (byte) 147, 80, (byte) 147, 18, 36, 17, 1, 32, (byte) 145, 17, 4, 84, 0, (byte) 145, 3, 1, 6, 0, 0, 0, 0, 0, 3, 116, 87, (byte) 175, 116, 7, (byte) 174, (byte) 206, (byte) 244, 15, (byte) 227, (byte) 162, 68, 9, (byte) 244, (byte) 236, 73, 59, 3, 84, 120, (byte) 132, (byte) 182, (byte) 174, (byte) 176, 80, (byte) 195, 0, 17, 1, 32, 3, (byte) 246, 61, 13, (byte) 255, (byte) 255, (byte) 144, 0};
public static String b(byte[] bArr, int i) {
byte[] bArr2 = new byte[(i * 2)];
int i2 = 0;
int i3 = 0;
for (byte b2 : bArr) {
if (i2 >= i) {
break;
}
i2++;
int i4 = b2 & 255;
int i5 = i3 + 1;
byte[] bArr3 = f1504a;
bArr2[i3] = bArr3[i4 >>> 4];
i3 = i5 + 1;
bArr2[i5] = bArr3[i4 & 15];
}
return new String(bArr2);
}
b(bArr, 8);
RESULT IS : 6032986093509312
how to convert to dart or flutter.
thanks for answering i'm very appreciate
The answer from julemand101 is a perfect translation of the Java code.
A more idiomatic Dart version could be something like:
import 'dart:typed_data';
final byteTable = Uint8List.fromList([
96, 50, 152, 96, 147, 80, 147, 18, 36, 17, 1, 32, 145, 17, 4, 84, 0, 145, //
3, 1, 6, 0, 0, 0, 0, 0, 3, 116, 87, 175, 116, 7, 174, 206, 244, 15, 227, //
162, 68, 9, 244, 236, 73, 59, 3, 84, 120, 132, 182, 174, 176, 80, 195, 0, //
17, 1, 32, 3, 246, 61, 13, 255, 255, 144, 0
]);
// The hex representation of the first [length] bytes of [bytes].
String toHex(Uint8List bytes, int length) {
const hexDigits = "0123456789ABCDEF";
final resultBytes = Uint8List(length * 2);
if (length > bytes.length) length = bytes.length;
for (var i = 0, j = 0; i < length; i++) {
var byte = bytes[i];
resultBytes[j++] = hexDigits.codeUnitAt(byte >> 4);
resultBytes[j++] = hexDigits.codeUnitAt(byte & 15);
}
return String.fromCharCodes(resultBytes);
}
void main() {
print(toHex(byteTable, 8)); // 6032986093509312
}
Please read the comments you got on your question. You should not expect Stackoverflow to just be a service where you can get other people to do your work.
When that said, I got some spare time and ended up writing a solution in Dart for your code as some kind of puzzle. Not entirely sure if it works the same as your Java code but it works for that one example you have provided:
import 'dart:typed_data';
Uint8List f1504a = Uint8List.fromList(
[48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70]);
Uint8List bArr = Uint8List.fromList([
96, 50, 152, 96, 147, 80, 147, 18, 36, 17, 1, 32, 145, 17, 4, 84, 0, 145, //
3, 1, 6, 0, 0, 0, 0, 0, 3, 116, 87, 175, 116, 7, 174, 206, 244, 15, 227, //
162, 68, 9, 244, 236, 73, 59, 3, 84, 120, 132, 182, 174, 176, 80, 195, 0, //
17, 1, 32, 3, 246, 61, 13, 255, 255, 144, 0
]);
String b(Uint8List bArr, int i) {
final bArr2 = Uint8List(i * 2);
var i2 = 0, i3 = 0;
for (final b2 in bArr) {
if (i2 >= i) {
break;
}
i2++;
final i4 = b2 & 255;
final i5 = i3 + 1;
final bArr3 = f1504a;
bArr2[i3] = bArr3[i4 >> 4];
i3 = i5 + 1;
bArr2[i5] = bArr3[i4 & 15];
}
return String.fromCharCodes(bArr2);
}
void main() {
print(b(bArr, 8)); // 6032986093509312
}

Love2d / LUA grid locked movement NO DIAGONAL

I thought this would be a common problem but after days of research I can't find a solution. Very new to programming in general and LUA specifically. I'm building a SUPAPLEX clone as a CS50 personal project: the character moves along the grid based map and there's a code that everyone seems to suggest (attached). On release of arrow buttons the movement is continued until the end of a tile, smoothly. But if 2 movement buttons are pushed, it causes brief diagonal movement and that's the problem I'm unsuccessfully trying to solve.
Basically I'm trying to either ignore any input until the movement of the sprite is finished at the end of the grid tile or prevent updating until movement in one direction is complete. Seems like a simple thing but I'm about to give up this whole thing. Frustrating. Any input is hiiiighly appreciated and I'm sure this would be a lot of help for very many people...
function love.load()
love.keyboard.setKeyRepeat(true)
player = {
grid_x = 256,
grid_y = 256,
act_x = 256,
act_y = 256,
speed = 5,
}
map = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
}
function testMap(x, y)
if map[(player.grid_y / 32) + y][(player.grid_x / 32) + x] == 1 then
return false
end
return true
end
function love.keypressed(key)
if key == "up" then
player.grid_y = player.grid_y - 32
elseif key == "down" then
player.grid_y = player.grid_y + 32
elseif key == "left" then
player.grid_x = player.grid_x - 32
elseif key == "right" then
player.grid_x = player.grid_x + 32
end
end
end
function love.update(dt)
player.act_y = player.act_y - ((player.act_y - player.grid_y) * player.speed * dt)
player.act_x = player.act_x - ((player.act_x - player.grid_x) * player.speed * dt)
end
function love.draw()
love.graphics.rectangle("fill", player.act_x, player.act_y, 32, 32)
for y=1, #map do
for x=1, #map[y] do
if map[y][x] == 1 then
love.graphics.rectangle("line", x * 32, y * 32, 32, 32)
end
end
end
end
you're trying to get it to only walk along grid-lines?
take out love.keyboard.setKeyRepeat(true)
and don't use love.keypressed(key)
that's for one-at-a-time keypresses, and it would be hard to use that
with love.keyreleased() to see if all the other keys are released.
use isDown instead, and if one of them isDown, then none of the other dir keys allow input. (along with the couple player.act lines you already have in your update)
player = {
grid_x = 256,
grid_y = 256,
act_x = 256,
act_y = 256,
speed = 5,
dir = ''
}
function love.update(dt)
if love.keyboard.isDown("up", "down", "left", "right") then
if love.keyboard.isDown("up") and ( player.dir == 'up' or player.dir == '' ) then
player.dir = 'up' -- only go up if currently held, or no other dir key being pressed
player.grid_y = player.grid_y - 32
elseif love.keyboard.isDown("down") and ( player.dir == 'down' or player.dir == '' ) then
player.dir = 'down' -- only go down if currently held...
player.grid_y = player.grid_y + 32
elseif key == "left" and ( player.dir == 'left' or player.dir == '' ) then
player.dir = 'left'
player.grid_x = player.grid_x - 32
elseif key == "right" and ( player.dir == 'right' or player.dir == '' ) then
player.dir = 'right'
player.grid_x = player.grid_x + 32
end
else -- none of those keys are being pressed, so player is idle
player.dir = ''
end -- isDown()
player.act_y = player.act_y - ((player.act_y - player.grid_y) * player.speed * dt)
player.act_x = player.act_x - ((player.act_x - player.grid_x) * player.speed * dt)
end -- update()

Lua Error: Main.lua:131: attempt to index local ‘up’ (a nil value) stack traceback:

I've a game project due in the next month(simple maze game) but I keep running into this error. I'd really appreciate it if someone took a look at it. I'm new to Lua so it's probably very simple. The error seems to be originating around line 131. I've put line 131 between a load of stars (*****...). You'd make my day if you took a few minutes to look at it. :) The error is : Main.lua:131: attempt to index local ‘up’ (a nil value) stack traceback:
local screenWidth = display.contentWidth
local screenHeight = display.contentHeight
local controllerWidth = screenWidth / 6
local rightMargin = 30
local maze = {
{ 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
{ 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1 },
{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 },
}
maze.rows = table.getn(maze)
maze.columns = table.getn(maze[1])
maze.xStart, maze.yStart = 1, 1
maze.xFinish, maze.yFinish = 24, 7
local grid = {}
grid.xSquares = maze.columns
grid.ySquares = maze.rows
grid.totalWidth = screenWidth - controllerWidth - rightMargin
grid.squareSize = grid.totalWidth / grid.xSquares
grid.xStart = controllerWidth
grid.yStart = 60
grid.displayGroup = display.newGroup()
grid.displayGroup.x = grid.xStart
grid.displayGroup.y = grid.yStart
grid.functions = {
left = function(gridSquare)
if gridSquare.x == 0 then
return gridSquare
else
return grid[gridSquare.y][gridSquare.x - 1]
end
end,
right = function(gridSquare)
if gridSquare.x + 1 == grid.xSquares then
return gridSquare
else
return grid[gridSquare.y][gridSquare.x + 1]
end
end,
above = function(gridSquare)
if gridSquare.y == 0 then
return gridSquare
else
return grid[gridSquare.y - 1][gridSquare.x]
end
end,
below = function(gridSquare)
if gridSquare.y + 1 == grid.ySquares then
return gridSquare
else
return grid[gridSquare.y + 1][gridSquare.x]
end
end,
}
for y = 0, grid.ySquares - 1 do
grid[y] = {y = y}
for x = 0, grid.xSquares - 1 do
grid[y][x] = {x = x, y = y}
local rect = display.newRect(grid.displayGroup,
grid.squareSize * x, grid.squareSize * y,
grid.squareSize, grid.squareSize)
if maze[y + 1][x + 1] == 0 then
rect:setFillColor(245, 215, 98)
else
grid[y][x].wall = true
rect:setFillColor(32, 96, 32, 255)
end
grid[y][x].displayObject = rect
grid[y][x].left = grid.functions.left
grid[y][x].right = grid.functions.right
grid[y][x].above = grid.functions.above
grid[y][x].below = grid.functions.below
end
end
grid[maze.yStart - 1][maze.xStart - 1].start = true
grid[maze.yStart - 1][maze.xStart - 1].displayObject:setFillColor(192, 192, 255)
grid[maze.yFinish - 1][maze.xFinish - 1].displayObject:setFillColor(192, 128, 128)
grid[maze.yStart - 1][maze.xStart - 1].start = true
grid[maze.yFinish - 1][maze.xFinish - 1].finish = true
local runner = { image = "runner.png" }
function runner:enter(gridSquare)
if self.displayObject == nil then
self.displayObject = display.newImageRect(grid.displayGroup,
self.image, grid.squareSize, grid.squareSize)
self.displayObject:setFillColor(92, 92, 92)
end
self.displayObject.x = gridSquare.displayObject.x
self.displayObject.y = gridSquare.displayObject.y
self.gridSquare = gridSquare
self.x = gridSquare.x
self.y = gridSquare.y
if self.gridSquare.finish then
finish()
end
end
function runner:canEnter(gridSquare)
return gridSquare.wall == nil
end
local controlCenterX = controllerWidth / 2
local controlCenterY = screenHeight - screenHeight / 5
local controlCenterRadius = controllerWidth / 2 - rightMargin
local upDownWidth = 27
local upDownHeight = 60
local leftRightWidth = 60
local leftRightHeight = 27
local controls = {
up = {},
down = {},
right = {},
left = {},
}
controls.displayGroup = display.newGroup()
local circlePad = display.newCircle(controls.displayGroup,
controlCenterX, controlCenterY, controlCenterRadius)
circlePad:setFillColor(128, 128, 128)
******
local up = display.newImageRect(controls.displayGroup, "arrow_up.png",
upDownWidth, upDownHeight)
up.x = controlCenterX
up.y = controlCenterY - upDownHeight / 2
controls.up.displayObject = up
******
local down = display.newImageRect(controls.displayGroup, "arrow_down.png",
upDownWidth, upDownHeight)
down.x = controlCenterX
down.y = controlCenterY + upDownHeight / 2
controls.down.displayObject = down
local right = display.newImageRect(controls.displayGroup, "arrow_right.png",
leftRightWidth, leftRightHeight)
right.x = controlCenterX + leftRightWidth / 2
right.y = controlCenterY
controls.right.displayObject = right
local left = display.newImageRect(controls.displayGroup, "arrow_left.png",
leftRightWidth, leftRightHeight)
left.x = controlCenterX - leftRightWidth / 2
left.y = controlCenterY
controls.left.displayObject = left
controls.hide = function(controls)
controls.displayGroup.isVisible = false
end
controls.show = function(controls)
controls.displayGroup.isVisible = true
end
local function pressLeft(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:left()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
local function pressRight(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:right()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
local function pressUp(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:above()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
local function pressDown(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:below()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
controls.left.displayObject:addEventListener("touch", pressLeft)
controls.right.displayObject:addEventListener("touch", pressRight)
controls.up.displayObject:addEventListener("touch", pressUp)
controls.down.displayObject:addEventListener("touch", pressDown)
local startButton = {}
startButton.displayGroup = display.newGroup()
startButton.displayObject = display.newCircle(startButton.displayGroup,
controlCenterX, controlCenterY, controlCenterRadius)
startButton.displayObject.strokeWidth = 6
startButton.displayObject:setStrokeColor(244, 244, 64)
startButton.text = display.newText(startButton.displayGroup,
"Start", controlCenterX - controlCenterRadius + 20, controlCenterY - 18,
native.systemFont, 24)
startButton.text:setTextColor(0, 0, 0)
startButton.touch = function(event)
if event.phase == "began" then
startButton:hide()
start()
end
end
startButton.displayGroup:addEventListener("touch", startButton.touch)
startButton.show = function(button)
button.displayGroup.isVisible = true
end
startButton.hide = function(button)
button.displayGroup.isVisible = false
end
local playAgainButton = {}
playAgainButton.displayGroup = display.newGroup()
playAgainButton.displayObject = display.newCircle(playAgainButton.displayGroup,
controlCenterX, controlCenterY, controlCenterRadius)
playAgainButton.displayObject.strokeWidth = 6
playAgainButton.displayObject:setStrokeColor(244, 244, 64)
playAgainButton.text = display.newText(playAgainButton.displayGroup,
"Again", controlCenterX - controlCenterRadius + 20, controlCenterY - 18,
native.systemFont, 24)
playAgainButton.text:setTextColor(0, 0, 0)
playAgainButton.touch = function(event)
if event.phase == "began" then
playAgainButton:hide()
play()
end
end
playAgainButton.displayGroup:addEventListener("touch", playAgainButton.touch)
playAgainButton.show = startButton.show
playAgainButton.hide = startButton.hide
function play()
runner:enter(grid[maze.yStart - 1][maze.xStart - 1])
playAgainButton:hide()
controls:hide()
startButton:show()
end
function start()
controls:show()
end
function finish()
controls:hide()
playAgainButton:show()
end
play()

Attempt to index local ‘up’ (a nil value) (LUA)

Main.lua:131 attempt to index local ‘up’ (a nil value)
Hi Guys,
Hope you’re having a good day.
I appologise if the error I’ve made is really simple. I’m new to lua and am still figuring it out. If you have a few minutes to spare I’d really appreciate if you took a look at the code.
The error I’m getting is: Main.lua:131 attempt to index local ‘up’ (a nil value)
I’ve put line 131 and the line I believe to be causing the error in stars so you don’t have to count every line.
I don’t think controls.displayGroup has been initialized correctly but I’m not sure how to fix it.
local screenWidth = display.contentWidth
local screenHeight = display.contentHeight
local controllerWidth = screenWidth / 6
local rightMargin = 30
local maze = {
{ 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
{ 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1 },
{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 },
}
maze.rows = table.getn(maze)
maze.columns = table.getn(maze[1])
maze.xStart, maze.yStart = 1, 1
maze.xFinish, maze.yFinish = 24, 7
local grid = {}
grid.xSquares = maze.columns
grid.ySquares = maze.rows
grid.totalWidth = screenWidth - controllerWidth - rightMargin
grid.squareSize = grid.totalWidth / grid.xSquares
grid.xStart = controllerWidth
grid.yStart = 60
grid.displayGroup = display.newGroup()
grid.displayGroup.x = grid.xStart
grid.displayGroup.y = grid.yStart
grid.functions = {
left = function(gridSquare)
if gridSquare.x == 0 then
return gridSquare
else
return grid[gridSquare.y][gridSquare.x - 1]
end
end,
right = function(gridSquare)
if gridSquare.x + 1 == grid.xSquares then
return gridSquare
else
return grid[gridSquare.y][gridSquare.x + 1]
end
end,
above = function(gridSquare)
if gridSquare.y == 0 then
return gridSquare
else
return grid[gridSquare.y - 1][gridSquare.x]
end
end,
below = function(gridSquare)
if gridSquare.y + 1 == grid.ySquares then
return gridSquare
else
return grid[gridSquare.y + 1][gridSquare.x]
end
end,
}
for y = 0, grid.ySquares - 1 do
grid[y] = {y = y}
for x = 0, grid.xSquares - 1 do
grid[y][x] = {x = x, y = y}
local rect = display.newRect(grid.displayGroup,
grid.squareSize * x, grid.squareSize * y,
grid.squareSize, grid.squareSize)
if maze[y + 1][x + 1] == 0 then
rect:setFillColor(245, 215, 98)
else
grid[y][x].wall = true
rect:setFillColor(32, 96, 32, 255)
end
grid[y][x].displayObject = rect
grid[y][x].left = grid.functions.left
grid[y][x].right = grid.functions.right
grid[y][x].above = grid.functions.above
grid[y][x].below = grid.functions.below
end
end
grid[maze.yStart - 1][maze.xStart - 1].start = true
grid[maze.yStart - 1][maze.xStart - 1].displayObject:setFillColor(192, 192, 255)
grid[maze.yFinish - 1][maze.xFinish - 1].displayObject:setFillColor(192, 128, 128)
grid[maze.yStart - 1][maze.xStart - 1].start = true
grid[maze.yFinish - 1][maze.xFinish - 1].finish = true
local runner = { image = "runner.png" }
function runner:enter(gridSquare)
if self.displayObject == nil then
self.displayObject = display.newImageRect(grid.displayGroup,
self.image, grid.squareSize, grid.squareSize)
self.displayObject:setFillColor(92, 92, 92)
end
self.displayObject.x = gridSquare.displayObject.x
self.displayObject.y = gridSquare.displayObject.y
self.gridSquare = gridSquare
self.x = gridSquare.x
self.y = gridSquare.y
if self.gridSquare.finish then
finish()
end
end
function runner:canEnter(gridSquare)
return gridSquare.wall == nil
end
local controlCenterX = controllerWidth / 2
local controlCenterY = screenHeight - screenHeight / 5
local controlCenterRadius = controllerWidth / 2 - rightMargin
local upDownWidth = 27
local upDownHeight = 60
local leftRightWidth = 60
local leftRightHeight = 27
local controls = {
up = {},
down = {},
right = {},
left = {},
}
****
controls.displayGroup = display.newGroup()
****
local circlePad = display.newCircle(controls.displayGroup,
controlCenterX, controlCenterY, controlCenterRadius)
circlePad:setFillColor(128, 128, 128)
*****
local up = display.newImageRect(controls.displayGroup, "arrow_up.png",
upDownWidth, upDownHeight)
up.x = controlCenterX
up.y = controlCenterY - upDownHeight / 2
controls.up.displayObject = up
*****
local down = display.newImageRect(controls.displayGroup, "arrow_down.png",
upDownWidth, upDownHeight)
down.x = controlCenterX
down.y = controlCenterY + upDownHeight / 2
controls.down.displayObject = down
local right = display.newImageRect(controls.displayGroup, "arrow_right.png",
leftRightWidth, leftRightHeight)
right.x = controlCenterX + leftRightWidth / 2
right.y = controlCenterY
controls.right.displayObject = right
local left = display.newImageRect(controls.displayGroup, "arrow_left.png",
leftRightWidth, leftRightHeight)
left.x = controlCenterX - leftRightWidth / 2
left.y = controlCenterY
controls.left.displayObject = left
controls.hide = function(controls)
controls.displayGroup.isVisible = false
end
controls.show = function(controls)
controls.displayGroup.isVisible = true
end
local function pressLeft(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:left()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
local function pressRight(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:right()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
local function pressUp(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:above()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
local function pressDown(event)
if event.phase == "began" then
local nextSquare = runner.gridSquare:below()
if runner:canEnter(nextSquare) then
runner:enter(nextSquare)
end
end
end
controls.left.displayObject:addEventListener("touch", pressLeft)
controls.right.displayObject:addEventListener("touch", pressRight)
controls.up.displayObject:addEventListener("touch", pressUp)
controls.down.displayObject:addEventListener("touch", pressDown)
local startButton = {}
startButton.displayGroup = display.newGroup()
startButton.displayObject = display.newCircle(startButton.displayGroup,
controlCenterX, controlCenterY, controlCenterRadius)
startButton.displayObject.strokeWidth = 6
startButton.displayObject:setStrokeColor(244, 244, 64)
startButton.text = display.newText(startButton.displayGroup,
"Start", controlCenterX - controlCenterRadius + 20, controlCenterY - 18,
native.systemFont, 24)
startButton.text:setTextColor(0, 0, 0)
startButton.touch = function(event)
if event.phase == "began" then
startButton:hide()
start()
end
end
startButton.displayGroup:addEventListener("touch", startButton.touch)
startButton.show = function(button)
button.displayGroup.isVisible = true
end
startButton.hide = function(button)
button.displayGroup.isVisible = false
end
local playAgainButton = {}
playAgainButton.displayGroup = display.newGroup()
playAgainButton.displayObject = display.newCircle(playAgainButton.displayGroup,
controlCenterX, controlCenterY, controlCenterRadius)
playAgainButton.displayObject.strokeWidth = 6
playAgainButton.displayObject:setStrokeColor(244, 244, 64)
playAgainButton.text = display.newText(playAgainButton.displayGroup,
"Again", controlCenterX - controlCenterRadius + 20, controlCenterY - 18,
native.systemFont, 24)
playAgainButton.text:setTextColor(0, 0, 0)
playAgainButton.touch = function(event)
if event.phase == "began" then
playAgainButton:hide()
play()
end
end
playAgainButton.displayGroup:addEventListener("touch", playAgainButton.touch)
playAgainButton.show = startButton.show
playAgainButton.hide = startButton.hide
function play()
runner:enter(grid[maze.yStart - 1][maze.xStart - 1])
playAgainButton:hide()
controls:hide()
startButton:show()
end
function start()
controls:show()
end
function finish()
controls:hide()
playAgainButton:show()
end
play()
display.newImageRect will return nothing, being the variable nil, if the image file doesn't exist, you might have noticed this already by checking the console, to fix this issue it's as easy as adding the missing assets to the project folder!

Detect all occurrences of same image

My script recognizes the given image, but if two of the same images are present it will ignore the second one. I want to count it as found 2 times at different locations. There are five rows where the same text-image can appear:
Screen
Image
Output from line 113
[Results found]: Additional Damage of Critical Hits +1% found.
Source code (excerpt)
Func Awakes_adoch()
ToolTip('Scanning for adoch awakes', 0, 0)
$adoch1 = _ImageSearchArea("images/adoch/adoch1.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch1 = 1) Then
$awake_adoch_attribute_count += 1
EndIf
$adoch3 = _ImageSearchArea("images/adoch/adoch3.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch3 = 1) Then
$awake_adoch_attribute_count += 3
EndIf
$adoch5 = _ImageSearchArea("images/adoch/adoch5.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch5 = 1) Then
$awake_adoch_attribute_count += 5
EndIf
$adoch7 = _ImageSearchArea("images/adoch/adoch7.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch7 = 1) Then
$awake_adoch_attribute_count += 7
EndIf
$adoch9 = _ImageSearchArea("images/adoch/adoch9.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch9 = 1) Then
$awake_adoch_attribute_count += 9
EndIf
$adoch11 = _ImageSearchArea("images/adoch/adoch11.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch11 = 1) Then
$awake_adoch_attribute_count += 11
EndIf
$adoch13 = _ImageSearchArea("images/adoch/adoch13.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch13 = 1) Then
$awake_adoch_attribute_count += 13
EndIf
$adoch15 = _ImageSearchArea("images/adoch/adoch15.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch15 = 1) Then
$awake_adoch_attribute_count += 15
EndIf
$adoch17 = _ImageSearchArea("images/adoch/adoch17.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch17 = 1) Then
$awake_adoch_attribute_count += 17
EndIf
$adoch19 = _ImageSearchArea("images/adoch/adoch19.png", 1, 0, 0, 400, 390, $x, $y, 0)
If ($adoch19 = 1) Then
$awake_adoch_attribute_count += 19
EndIf
Sleep(50)
ToolTip('[Scan]: Additional Damage of Critical Hits +' & $awake_adoch_attribute_count & '% found.', 0, 0)
EndFunc
Source code (full)
If the output window shows like below, it should be able to add up to 25:
Additional Damage of Critical Hits +3%
DEF + 40
Additional Damage of Critical Hits +3%
DEF + 4
Additional Damage of Critical Hits +19%
Another example:
I’m looking for a solution that doesn’t skip numbers or adds them from a previous shot to the next.
Source code (new)
relatively easy, as all searched images are below each other (would be much more difficult, when searched images were at random locations):
#include "ImageSearch64.au3"
$searchpath = "c:\users\50022505\Downloads\" ; where are my images?
$x = 0 ; dummy parameter for coordinates
$y = 0 ; dummy parameter for coordinates
$Damage = 100
ConsoleWrite("Initial Damage: " & $Damage & #CRLF)
AddDamage()
ConsoleWrite("Resulting Damage: " & $Damage & #CRLF)
Func AddDamage()
$Damage += GetLocations($searchpath & "adoch1.png")
$Damage += GetLocations($searchpath & "adoch5.png") * 5
$Damage += GetLocations($searchpath & "adoch9.png") * 9
$Damage += GetLocations($searchpath & "adoch11.png") * 11
Return $Damage
EndFunc ;==>AddDamage
Func GetLocations($search)
Local $Findings = 0, $found = 0
Local $dx = 0, $dy = 0 ;sub coordinates
While 1
Local $found = _ImageSearchArea($search, 1, $dx, $dy, 400, 390, $x, $y, 0)
If $found = 0 Then Return $Findings ; no more findings
$Findings += 1
$dy = $y ; set new coordinate window to search (excluding last finding)
WEnd
EndFunc ;==>GetLocations

Resources